2002-06-19 Jeff Johnston <jjohnstn@redhat.com>
* libc/sys/linux/Makefile.am: Add support for message queue routines,
        ipc routines, and ftok.
        * libc/sys/linux/Makefile.in: Regenerated.
        * libc/sys/linux/ftok.c: New file.
        * libc/sys/linux/ipc.c: Ditto.
        * libc/sys/linux/mq_close.c: Ditto.
        * libc/sys/linux/mq_getattr.c: Ditto.
        * libc/sys/linux/mq_notify.c: Ditto.
        * libc/sys/linux/mq_open.c: Ditto.
        * libc/sys/linux/mq_receive.c: Ditto.
        * libc/sys/linux/mq_send.c: Ditto.
        * libc/sys/linux/mq_setattr.c: Ditto.
        * libc/sys/linux/mq_unlink.c: Ditto.
        * libc/sys/linux/mqlocal.h: Ditto.
        * libc/sys/linux/include/mqueue.h: Ditto.
        * libc/sys/linux/sys/types.h: Define __gid_t_defined and
        __uid_t_defined.
			
			
This commit is contained in:
		| @@ -1,3 +1,23 @@ | ||||
| 2002-06-19  Jeff Johnston  <jjohnstn@redhat.com> | ||||
|  | ||||
|         * libc/sys/linux/Makefile.am: Add support for message queue routines, | ||||
|         ipc routines, and ftok. | ||||
|         * libc/sys/linux/Makefile.in: Regenerated. | ||||
|         * libc/sys/linux/ftok.c: New file. | ||||
|         * libc/sys/linux/ipc.c: Ditto. | ||||
|         * libc/sys/linux/mq_close.c: Ditto. | ||||
|         * libc/sys/linux/mq_getattr.c: Ditto. | ||||
|         * libc/sys/linux/mq_notify.c: Ditto. | ||||
|         * libc/sys/linux/mq_open.c: Ditto. | ||||
|         * libc/sys/linux/mq_receive.c: Ditto. | ||||
|         * libc/sys/linux/mq_send.c: Ditto. | ||||
|         * libc/sys/linux/mq_setattr.c: Ditto. | ||||
|         * libc/sys/linux/mq_unlink.c: Ditto. | ||||
|         * libc/sys/linux/mqlocal.h: Ditto. | ||||
|         * libc/sys/linux/include/mqueue.h: Ditto. | ||||
|         * libc/sys/linux/sys/types.h: Define __gid_t_defined and | ||||
|         __uid_t_defined. | ||||
|  | ||||
| 2002-06-19  J"orn Rennecke <joern.rennecke@superh.com> | ||||
|  | ||||
| 	* libm/common/sf_lround.c (round): Change name to: (lround). | ||||
| @@ -186,9 +206,6 @@ Thu Jun 13 19:23:40 2002  J"orn Rennecke <joern.rennecke@superh.com> | ||||
|         * libc/sys/linux/sigaction.c: New file. | ||||
|         * libc/sys/linux/signal.c: Changed to be linux signal() function | ||||
|         so as to override regular newlib default signal.c. | ||||
|         * libc/sys/linux/linuxthreads/config.h: Add __ASSUME_REALTIME_SIGNALS | ||||
|         definition. | ||||
|         * libc/sys/linux/linuxthreads/testrtsig.h: New file. | ||||
|         * libc/sys/linux/machine/i386/Makefile.am: Remove sigset.c. | ||||
|         * libc/sys/linux/machine/i386/Makefile.in: Regenerated. | ||||
|         * libc/sys/linux/machine/i386/sigset.c: Moved to linux main directory. | ||||
|   | ||||
| @@ -13,6 +13,7 @@ LIB_SOURCES = \ | ||||
| 	brk.c \ | ||||
| 	cfspeed.c \ | ||||
| 	flockfile.c \ | ||||
| 	ftok.c \ | ||||
| 	funlockfile.c \ | ||||
| 	gethostname.c \ | ||||
| 	getoptlong.c \ | ||||
| @@ -21,8 +22,17 @@ LIB_SOURCES = \ | ||||
| 	inode.c \ | ||||
| 	io.c \ | ||||
| 	io64.c \ | ||||
| 	ipc.c \ | ||||
| 	linux.c \ | ||||
| 	mmap.c \ | ||||
| 	mq_close.c \ | ||||
| 	mq_getattr.c \ | ||||
| 	mq_notify.c \ | ||||
| 	mq_open.c \ | ||||
| 	mq_receive.c \ | ||||
| 	mq_send.c \ | ||||
| 	mq_setattr.c \ | ||||
| 	mq_unlink.c \ | ||||
| 	pread.c \ | ||||
| 	pread64.c \ | ||||
| 	process.c \ | ||||
|   | ||||
| @@ -110,6 +110,7 @@ LIB_SOURCES = \ | ||||
| 	brk.c \ | ||||
| 	cfspeed.c \ | ||||
| 	flockfile.c \ | ||||
| 	ftok.c \ | ||||
| 	funlockfile.c \ | ||||
| 	gethostname.c \ | ||||
| 	getoptlong.c \ | ||||
| @@ -118,8 +119,17 @@ LIB_SOURCES = \ | ||||
| 	inode.c \ | ||||
| 	io.c \ | ||||
| 	io64.c \ | ||||
| 	ipc.c \ | ||||
| 	linux.c \ | ||||
| 	mmap.c \ | ||||
| 	mq_close.c \ | ||||
| 	mq_getattr.c \ | ||||
| 	mq_notify.c \ | ||||
| 	mq_open.c \ | ||||
| 	mq_receive.c \ | ||||
| 	mq_send.c \ | ||||
| 	mq_setattr.c \ | ||||
| 	mq_unlink.c \ | ||||
| 	pread.c \ | ||||
| 	pread64.c \ | ||||
| 	process.c \ | ||||
| @@ -186,12 +196,18 @@ DEFS = @DEFS@ -I. -I$(srcdir) | ||||
| CPPFLAGS = @CPPFLAGS@ | ||||
| LIBS = @LIBS@ | ||||
| @USE_LIBTOOL_FALSE@lib_a_OBJECTS =  brk.$(OBJEXT) cfspeed.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@flockfile.$(OBJEXT) funlockfile.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@gethostname.$(OBJEXT) getoptlong.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@getreent.$(OBJEXT) ids.$(OBJEXT) inode.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@io.$(OBJEXT) io64.$(OBJEXT) linux.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mmap.$(OBJEXT) pread.$(OBJEXT) pread64.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@process.$(OBJEXT) psignal.$(OBJEXT) pwrite.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@flockfile.$(OBJEXT) ftok.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@funlockfile.$(OBJEXT) gethostname.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@getoptlong.$(OBJEXT) getreent.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@ids.$(OBJEXT) inode.$(OBJEXT) io.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@io64.$(OBJEXT) ipc.$(OBJEXT) linux.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mmap.$(OBJEXT) mq_close.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mq_getattr.$(OBJEXT) mq_notify.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mq_open.$(OBJEXT) mq_receive.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mq_send.$(OBJEXT) mq_setattr.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mq_unlink.$(OBJEXT) pread.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@pread64.$(OBJEXT) process.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@psignal.$(OBJEXT) pwrite.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@pwrite64.$(OBJEXT) raise.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@realpath.$(OBJEXT) rename.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@resource.$(OBJEXT) sched.$(OBJEXT) select.$(OBJEXT) \ | ||||
| @@ -209,16 +225,19 @@ LTLIBRARIES =  $(noinst_LTLIBRARIES) | ||||
|  | ||||
| @USE_LIBTOOL_TRUE@liblinux_la_DEPENDENCIES =  | ||||
| @USE_LIBTOOL_TRUE@liblinux_la_OBJECTS =  brk.lo cfspeed.lo flockfile.lo \ | ||||
| @USE_LIBTOOL_TRUE@funlockfile.lo gethostname.lo getoptlong.lo \ | ||||
| @USE_LIBTOOL_TRUE@getreent.lo ids.lo inode.lo io.lo io64.lo linux.lo \ | ||||
| @USE_LIBTOOL_TRUE@mmap.lo pread.lo pread64.lo process.lo psignal.lo \ | ||||
| @USE_LIBTOOL_TRUE@pwrite.lo pwrite64.lo raise.lo realpath.lo rename.lo \ | ||||
| @USE_LIBTOOL_TRUE@resource.lo sched.lo select.lo seteuid.lo shm_open.lo \ | ||||
| @USE_LIBTOOL_TRUE@shm_unlink.lo sig.lo sigaction.lo sigqueue.lo \ | ||||
| @USE_LIBTOOL_TRUE@signal.lo siglongjmp.lo sigset.lo sigwait.lo \ | ||||
| @USE_LIBTOOL_TRUE@socket.lo sleep.lo stack.lo strsignal.lo sysconf.lo \ | ||||
| @USE_LIBTOOL_TRUE@sysctl.lo systat.lo system.lo tcdrain.lo tcsendbrk.lo \ | ||||
| @USE_LIBTOOL_TRUE@termios.lo time.lo usleep.lo wait.lo | ||||
| @USE_LIBTOOL_TRUE@ftok.lo funlockfile.lo gethostname.lo getoptlong.lo \ | ||||
| @USE_LIBTOOL_TRUE@getreent.lo ids.lo inode.lo io.lo io64.lo ipc.lo \ | ||||
| @USE_LIBTOOL_TRUE@linux.lo mmap.lo mq_close.lo mq_getattr.lo \ | ||||
| @USE_LIBTOOL_TRUE@mq_notify.lo mq_open.lo mq_receive.lo mq_send.lo \ | ||||
| @USE_LIBTOOL_TRUE@mq_setattr.lo mq_unlink.lo pread.lo pread64.lo \ | ||||
| @USE_LIBTOOL_TRUE@process.lo psignal.lo pwrite.lo pwrite64.lo raise.lo \ | ||||
| @USE_LIBTOOL_TRUE@realpath.lo rename.lo resource.lo sched.lo select.lo \ | ||||
| @USE_LIBTOOL_TRUE@seteuid.lo shm_open.lo shm_unlink.lo sig.lo \ | ||||
| @USE_LIBTOOL_TRUE@sigaction.lo sigqueue.lo signal.lo siglongjmp.lo \ | ||||
| @USE_LIBTOOL_TRUE@sigset.lo sigwait.lo socket.lo sleep.lo stack.lo \ | ||||
| @USE_LIBTOOL_TRUE@strsignal.lo sysconf.lo sysctl.lo systat.lo system.lo \ | ||||
| @USE_LIBTOOL_TRUE@tcdrain.lo tcsendbrk.lo termios.lo time.lo usleep.lo \ | ||||
| @USE_LIBTOOL_TRUE@wait.lo | ||||
| CFLAGS = @CFLAGS@ | ||||
| COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||||
| LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||||
|   | ||||
							
								
								
									
										41
									
								
								newlib/libc/sys/linux/ftok.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								newlib/libc/sys/linux/ftok.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| /* Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995. | ||||
|  | ||||
|    The GNU C Library is free software; you can redistribute it and/or | ||||
|    modify it under the terms of the GNU Lesser General Public | ||||
|    License as published by the Free Software Foundation; either | ||||
|    version 2.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C Library is distributed in the hope that it will be useful, | ||||
|    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|    Lesser General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU Lesser General Public | ||||
|    License along with the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* Modified for newlib by Jeff Johnston, June 10/2002 */ | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/ipc.h> | ||||
| #include <sys/stat.h> | ||||
|  | ||||
| key_t | ||||
| ftok (pathname, proj_id) | ||||
|      const char *pathname; | ||||
|      int proj_id; | ||||
| { | ||||
|   struct stat64 st; | ||||
|   key_t key; | ||||
|  | ||||
|   if (stat64 (pathname, &st) < 0) | ||||
|     return (key_t) -1; | ||||
|  | ||||
|   key = ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ||||
| 	 | ((proj_id & 0xff) << 24)); | ||||
|  | ||||
|   return key; | ||||
| } | ||||
							
								
								
									
										34
									
								
								newlib/libc/sys/linux/include/mqueue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								newlib/libc/sys/linux/include/mqueue.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* libc/sys/linux/include/mqueue.h - message queue functions */ | ||||
|  | ||||
| /* Copyright 2002, Red Hat Inc. - all rights reserved */ | ||||
|  | ||||
| #ifndef __MQUEUE_H | ||||
| #define __MQUEUE_H | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #define __need_sigevent_t 1 | ||||
| #include <asm/siginfo.h> | ||||
|  | ||||
| /* message queue types */ | ||||
| typedef int mqd_t; | ||||
|  | ||||
| struct mq_attr { | ||||
|   long mq_flags;    /* message queue flags */ | ||||
|   long mq_maxmsg;   /* maximum number of messages */ | ||||
|   long mq_msgsize;  /* maximum message size */ | ||||
|   long mq_curmsgs;  /* number of messages currently queued */ | ||||
| }; | ||||
|  | ||||
| #define MQ_PRIO_MAX 16 | ||||
|  | ||||
| /* prototypes */ | ||||
| mqd_t mq_open (const char *__name, int __oflag, ...); | ||||
| int mq_close (mqd_t __msgid); | ||||
| int mq_send (mqd_t __msgid, const char *__msg, size_t __msg_len, unsigned int __msg_prio); | ||||
| ssize_t mq_receive (mqd_t __msgid, char *__msg, size_t __msg_len, unsigned int *__msg_prio); | ||||
| int mq_notify (mqd_t __msgid, const struct sigevent *__notification); | ||||
| int mq_unlink (const char *__name); | ||||
| int mq_getattr (mqd_t __msgid, struct mq_attr *__mqstat); | ||||
| int mq_setattr (mqd_t __msgid, const struct mq_attr *__mqstat, struct mq_attr *__omqattr); | ||||
|  | ||||
| #endif /* __MQUEUE_H */ | ||||
							
								
								
									
										87
									
								
								newlib/libc/sys/linux/ipc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								newlib/libc/sys/linux/ipc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| /* libc/sys/linux/ipc.c - IPC semaphore and message queue functions */ | ||||
|  | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/sem.h> | ||||
| #include <sys/msg.h> | ||||
| #include <stdarg.h> | ||||
|  | ||||
| #include <machine/syscall.h> | ||||
|  | ||||
| #define IPC_64 0x100 | ||||
|  | ||||
| #define IPCOP_semop	1 | ||||
| #define IPCOP_semget	2 | ||||
| #define IPCOP_semctl	3 | ||||
| #define IPCOP_msgsnd	11 | ||||
| #define IPCOP_msgrcv	12 | ||||
| #define IPCOP_msgget	13 | ||||
| #define IPCOP_msgctl	14 | ||||
|  | ||||
| static _syscall5(int,ipc,int,op,int,arg1,int,arg2,int,arg3,void *,arg4); | ||||
|  | ||||
| int | ||||
| semget (key_t key, int nsems, int semflgs) | ||||
| { | ||||
|   return __libc_ipc(IPCOP_semget, (int)key, nsems, semflgs, NULL); | ||||
| } | ||||
|  | ||||
| int | ||||
| semctl (int semid, int semnum, int cmd, ...) | ||||
| { | ||||
|   va_list va; | ||||
|   union semun { | ||||
|     int val; | ||||
|     struct semid_ds *buf; | ||||
|     unsigned short  *array; | ||||
|   } arg; | ||||
|  | ||||
|   va_start (va, cmd); | ||||
|  | ||||
|   arg = va_arg (va, union semun); | ||||
|  | ||||
|   va_end (va); | ||||
|  | ||||
|   return __libc_ipc(IPCOP_semctl, semid, semnum, cmd | IPC_64, &arg); | ||||
| } | ||||
|  | ||||
| int | ||||
| semop (int semid, struct sembuf *sops, size_t nsems) | ||||
| { | ||||
|   return __libc_ipc(IPCOP_semop, semid, (int)nsems, 0, sops); | ||||
| } | ||||
|  | ||||
| int | ||||
| msgget (key_t key, int msgflg) | ||||
| { | ||||
|   return __libc_ipc(IPCOP_msgget, (int)key, msgflg, 0, NULL); | ||||
| } | ||||
|  | ||||
| int | ||||
| msgctl (int msqid, int cmd, struct msqid_ds *buf) | ||||
| { | ||||
|   return __libc_ipc(IPCOP_msgctl, msqid, cmd | IPC_64, 0, buf); | ||||
| } | ||||
|  | ||||
| int | ||||
| msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg) | ||||
| { | ||||
|   return __libc_ipc(IPCOP_msgsnd, msqid, (int)msgsz, msgflg, (void *)msgp); | ||||
| } | ||||
|  | ||||
| int | ||||
| msgrcv (int msqid, void *msgp, size_t msgsz, long int msgtyp, int msgflg) | ||||
| { | ||||
|   /* last argument must contain multiple args */ | ||||
|   struct { | ||||
|     void *msgp; | ||||
|     long int msgtyp; | ||||
|   } args; | ||||
|  | ||||
|   args.msgp = msgp; | ||||
|   args.msgtyp = msgtyp; | ||||
|  | ||||
|   return (ssize_t)__libc_ipc(IPCOP_msgrcv, msqid, (int)msgsz, msgflg, &args); | ||||
| } | ||||
|  | ||||
							
								
								
									
										48
									
								
								newlib/libc/sys/linux/mq_close.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								newlib/libc/sys/linux/mq_close.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <mqueue.h> | ||||
| #include <errno.h> | ||||
| #include <sys/sem.h> | ||||
| #define _LIBC | ||||
| #include <sys/lock.h> | ||||
| #undef _LIBC | ||||
|  | ||||
| #include "mqlocal.h" | ||||
|  | ||||
| int | ||||
| mq_close (mqd_t msgid) | ||||
| { | ||||
|   struct libc_mq *info; | ||||
|   struct sembuf sb0 = {0, -1, 0}; | ||||
|   int rc; | ||||
|   int semid; | ||||
|  | ||||
|   info = __find_mq (msgid); | ||||
|  | ||||
|   if (info == NULL) | ||||
|     { | ||||
|       errno = EBADF; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   /* lock message queue */ | ||||
|   semid = info->semid; | ||||
|   rc = semop (semid, &sb0, 1); | ||||
|  | ||||
|   if (rc == 0) | ||||
|     { | ||||
|       __cleanup_mq (msgid); | ||||
|        | ||||
|       /* unlock message queue */ | ||||
|       sb0.sem_op = 1; | ||||
|       semop (semid, &sb0, 1); | ||||
|     } | ||||
|  | ||||
|   return rc; | ||||
| } | ||||
|        | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										52
									
								
								newlib/libc/sys/linux/mq_getattr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								newlib/libc/sys/linux/mq_getattr.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <mqueue.h> | ||||
| #include <errno.h> | ||||
| #include <sys/sem.h> | ||||
| #include <string.h> | ||||
| #define _LIBC | ||||
| #include <sys/lock.h> | ||||
| #undef _LIBC | ||||
|  | ||||
| #include "mqlocal.h" | ||||
|  | ||||
| int | ||||
| mq_getattr (mqd_t msgid, struct mq_attr *mqstat) | ||||
| { | ||||
|   struct libc_mq *info; | ||||
|   struct sembuf sb0 = {0, -1, 0}; | ||||
|   int num_msgs; | ||||
|   int rc = 0; | ||||
|  | ||||
|   info = __find_mq (msgid); | ||||
|  | ||||
|   if (info == NULL) | ||||
|     { | ||||
|       errno = EBADF; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   /* temporarily lock message queue */ | ||||
|   semop (info->semid, &sb0, 1); | ||||
|  | ||||
|   num_msgs = semctl (info->semid, 3, GETVAL); | ||||
|   if (num_msgs >= 0) | ||||
|     { | ||||
|       memcpy (mqstat, info->attr, sizeof(struct mq_attr)); | ||||
|       mqstat->mq_curmsgs = num_msgs; | ||||
|     } | ||||
|   else | ||||
|     rc = -1; | ||||
|  | ||||
|   /* release message queue */ | ||||
|   sb0.sem_op = 1; | ||||
|   semop (info->semid, &sb0, 1); | ||||
|  | ||||
|   return rc; | ||||
| } | ||||
|        | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										22
									
								
								newlib/libc/sys/linux/mq_notify.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								newlib/libc/sys/linux/mq_notify.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <mqueue.h> | ||||
| #include <errno.h> | ||||
| #include <machine/weakalias.h> | ||||
|  | ||||
| #include "mqlocal.h" | ||||
|  | ||||
| int | ||||
| __libc_mq_notify (mqd_t msgid, const struct sigevent *notification) | ||||
| { | ||||
|   errno = ENOSYS; | ||||
|   return -1; | ||||
| } | ||||
| weak_alias (__libc_mq_notify, mq_notify) | ||||
|  | ||||
|        | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										340
									
								
								newlib/libc/sys/linux/mq_open.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								newlib/libc/sys/linux/mq_open.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,340 @@ | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <mqueue.h> | ||||
| #include <fcntl.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/ipc.h> | ||||
| #include <sys/sem.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <time.h> | ||||
| #include <stdarg.h> | ||||
| #include <machine/weakalias.h> | ||||
| #define _LIBC | ||||
| #include <sys/lock.h> | ||||
| #undef _LIBC | ||||
|  | ||||
| #include "mqlocal.h" | ||||
|  | ||||
| #define	NHASH	32	          /* Num of hash lists, must be a power of 2 */ | ||||
| #define	LOCHASH(i)	((i)&(NHASH-1)) | ||||
|  | ||||
| static long	mq_index;	/* Index of next entry */ | ||||
| static struct	libc_mq *mq_hash[NHASH];   /* Hash list heads for mqopen_infos */ | ||||
|  | ||||
| __LOCK_INIT(static, mq_hash_lock); | ||||
|  | ||||
| mqd_t | ||||
| mq_open (const char *name, int oflag, ...) | ||||
| { | ||||
|   MSG *wrbuf = NULL; | ||||
|   MSG *rdbuf = NULL; | ||||
|   int msgqid = -1; | ||||
|   int rc = -1; | ||||
|   int fd = -1; | ||||
|   int semid = -1; | ||||
|   int created = 0; | ||||
|   key_t key = (key_t)-1; | ||||
|   struct mq_attr *attr = (struct mq_attr *)MAP_FAILED; | ||||
|   struct sembuf sb = {0, 0, 0}; | ||||
|   mode_t mode = 0; | ||||
|   int size; | ||||
|   int i, index, saved_errno; | ||||
|   char *real_name; | ||||
|   char *ptr; | ||||
|   struct mq_attr *user_attr = NULL; | ||||
|   struct libc_mq *info; | ||||
|   union semun arg; | ||||
|    | ||||
|   /* ignore opening slash if present */ | ||||
|   if (*name == '/') | ||||
|     ++name;   | ||||
|   size = strlen(name); | ||||
|  | ||||
|   if ((real_name = (char *)malloc (size + sizeof(MSGQ_PREFIX))) == NULL || | ||||
|       (info = (struct libc_mq *)malloc (sizeof(struct libc_mq))) == NULL) | ||||
|     { | ||||
|       errno = ENOSPC; | ||||
|       if (real_name) | ||||
| 	free (real_name); | ||||
|       return (mqd_t)-1; | ||||
|     } | ||||
|    | ||||
|   /* use given name to create shared memory file name - we convert any | ||||
|      slashes to underscores so we don't have to create directories */ | ||||
|   memcpy (real_name, MSGQ_PREFIX, sizeof(MSGQ_PREFIX) - 1); | ||||
|   memcpy (real_name + sizeof(MSGQ_PREFIX) - 1, name, size + 1); | ||||
|   ptr = real_name + sizeof(MSGQ_PREFIX) - 1; | ||||
|   for (i = 0; i < size; ++i) | ||||
|     { | ||||
|       if (*ptr == '/') | ||||
| 	*ptr = '_'; | ||||
|       ++ptr; | ||||
|     } | ||||
|  | ||||
|   /* open shared memory file based on msg queue open flags and then use memory | ||||
|      file to create a unique key to use for semaphores, etc.. */ | ||||
|   if (oflag & O_CREAT) | ||||
|     { | ||||
|       va_list list; | ||||
|       va_start (list, oflag); | ||||
|  | ||||
|       saved_errno = errno; | ||||
|       mode = (mode_t)va_arg (list, int); | ||||
|       user_attr = va_arg(list,struct mq_attr *); | ||||
|       va_end (list); | ||||
|  | ||||
|       /* attempt to open the shared memory file for exclusive create so we know | ||||
| 	 whether we are the owners or not */ | ||||
|       fd = open (real_name, O_RDWR | O_CREAT | O_EXCL, mode); | ||||
|       if (fd < 0 && (oflag & O_EXCL)) | ||||
| 	{ | ||||
| 	  /* we failed and the user wanted exclusive create */ | ||||
| 	  free (real_name); | ||||
| 	  free (info); | ||||
| 	  return (mqd_t)-1; | ||||
| 	} | ||||
|       errno = saved_errno; | ||||
|       created = 1; | ||||
|     } | ||||
| 	   | ||||
|   if (fd < 0) | ||||
|     fd = open (real_name, O_RDWR, 0); | ||||
|  | ||||
|   if (fd >= 0) | ||||
|     key = ftok(real_name, 255); | ||||
|  | ||||
|   if (key != (key_t)-1) | ||||
|     /* memory map the shared memory file so we have a global shared data area to use */ | ||||
|     attr = (struct mq_attr *)mmap (0, sizeof(struct mq_attr), PROT_READ | PROT_WRITE, | ||||
| 				   MAP_SHARED, fd, 0); | ||||
|    | ||||
|   if (attr != (struct mq_attr *)MAP_FAILED) | ||||
|     { | ||||
|       /* we need semaphores to prevent multi-process race conditions on the | ||||
| 	 shared storage which contains a shared structure.  The following | ||||
| 	 are the ones we need. | ||||
| 	  | ||||
| 	 0 = open semaphore | ||||
| 	 1 = number of opens | ||||
| 	 2 = number of writes left until queue is full | ||||
| 	 3 = number of reads available in queue | ||||
| 	 4 = notify semaphore  | ||||
| 	 5 = number of readers */ | ||||
|       arg.val = 0; | ||||
|       /* make sure the creator of the shared memory file also is the creator of the | ||||
| 	 semaphores...this will ensure that it also creates the message queue */ | ||||
|       if (created) | ||||
| 	{ | ||||
| 	  saved_errno = errno; | ||||
| 	  semid = semget (key, 6, IPC_CREAT | IPC_EXCL | mode); | ||||
| 	  errno = saved_errno; | ||||
| 	  /* now that we have created the semaphore, we should initialize it */ | ||||
| 	  if (semid != -1) | ||||
| 	    semctl (semid, 0, SETVAL, arg); | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  /* if we didn't create the shared memory file but have gotten to here, we want | ||||
| 	     to ensure we haven't gotten ahead of the creator temporarily so we will | ||||
| 	     loop until the semaphore exists.  This ensures that the creator will be the | ||||
| 	     one to create the message queue with the correct mode and we will be blocked | ||||
| 	     by the open semaphore 0.  We impose a time limit to ensure something terrible | ||||
| 	     hasn't gone wrong. */ | ||||
| 	  struct timespec tms; | ||||
| 	  int i; | ||||
|  | ||||
| 	  tms.tv_sec = 0; | ||||
| 	  tms.tv_nsec = 10000; /* 10 microseconds */ | ||||
| 	  for (i = 0; i < 100; ++i) | ||||
| 	    { | ||||
| 	      if ((semid = semget (key, 6, 0)) != -1) | ||||
| 		break; | ||||
| 	      /* sleep in case we our a higher priority process */ | ||||
| 	      nanosleep (&tms, NULL); | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   if (semid != -1) | ||||
|     { | ||||
|       /* acquire main open semaphore if we didn't create it */ | ||||
|       if (!created) | ||||
| 	{ | ||||
| 	  sb.sem_op = -1; | ||||
| 	  rc = semop (semid, &sb, 1); | ||||
| 	} | ||||
|       else | ||||
| 	rc = 0; /* need this to continue below */ | ||||
|     } | ||||
|        | ||||
|   if (rc == 0) | ||||
|     { | ||||
|       if (created) | ||||
| 	{ | ||||
| 	  /* the creator must get here first so the message queue will be created */ | ||||
| 	  msgqid = msgget (key, IPC_CREAT | mode);  | ||||
| 	  if (msgqid >= 0) | ||||
| 	    { | ||||
| 	      /* we have created the message queue so check and set the attributes */ | ||||
| 	      if ((wrbuf = (MSG *)malloc (user_attr->mq_msgsize + sizeof(int))) == NULL || | ||||
| 		  (rdbuf = (MSG *)malloc (user_attr->mq_msgsize + sizeof(int))) == NULL || | ||||
| 		  user_attr == NULL || user_attr->mq_msgsize <= 0 || user_attr->mq_maxmsg <= 0) | ||||
| 		{ | ||||
| 		  /* we're out of space and we created the message queue so we should | ||||
| 		     try to remove it */ | ||||
| 		  msgctl (msgqid, IPC_RMID, NULL); | ||||
| 		  msgqid = -1; /* allow clean up to occur below */ | ||||
| 		  if (wrbuf && rdbuf) | ||||
| 		    errno = EINVAL; | ||||
| 		  else | ||||
| 		    errno = ENOSPC; | ||||
| 		} | ||||
| 	      else /* valid attributes */ | ||||
| 		{ | ||||
| 		  write (fd, user_attr, sizeof(struct mq_attr)); | ||||
| 		  attr->mq_curmsgs = 0; | ||||
| 		  attr->mq_flags = oflag & O_NONBLOCK; | ||||
| 		  arg.val = 0; | ||||
| 		  semctl (semid, 1, SETVAL, arg); /* number of opens starts at 0 */ | ||||
| 		  semctl (semid, 3, SETVAL, arg); /* number of reads available starts at 0 */ | ||||
| 		  semctl (semid, 5, SETVAL, arg); /* number of readers starts at 0 */ | ||||
| 		  arg.val = 1; | ||||
| 		  semctl (semid, 4, SETVAL, arg); /* notify semaphore */ | ||||
| 		  arg.val = user_attr->mq_maxmsg; | ||||
| 		  semctl (semid, 2, SETVAL, arg); /* number of writes left starts at mq_maxmsg */ | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|       else /* just open it */ | ||||
| 	msgqid = msgget (key, 0); | ||||
|        | ||||
|       /* release semaphore acquired earlier */ | ||||
|       sb.sem_op = 1; | ||||
|       semop (semid, &sb, 1); | ||||
|     } | ||||
|  | ||||
|   /* if we get here and we haven't got a message queue id, then we need to clean up  | ||||
|      our mess and return failure */ | ||||
|   if (msgqid < 0) | ||||
|     { | ||||
|       if (fd >= 0) | ||||
| 	close (fd); | ||||
|       if (attr != (struct mq_attr *)MAP_FAILED) | ||||
| 	munmap (attr, sizeof(struct mq_attr)); | ||||
|       if (created) | ||||
| 	{ | ||||
| 	  unlink (real_name); | ||||
| 	  if (semid != -1) | ||||
| 	    semctl (semid, 0, IPC_RMID); | ||||
| 	} | ||||
|       free (real_name); | ||||
|       free (info); | ||||
|       if (wrbuf) | ||||
| 	free (wrbuf); | ||||
|       if (rdbuf) | ||||
| 	free (rdbuf); | ||||
|       return (mqd_t)-1; | ||||
|     } | ||||
|  | ||||
|   /* we are successful so register the message queue */ | ||||
|  | ||||
|   /* up the count of msg queue opens */ | ||||
|   sb.sem_op = 1; | ||||
|   sb.sem_num = 1; | ||||
|   semop (semid, &sb, 1); | ||||
|  | ||||
|   /* success, translate into index into mq_info array */   | ||||
|   __lock_acquire(mq_hash_lock); | ||||
|   index = mq_index++; | ||||
|   info->index = index; | ||||
|   info->msgqid = msgqid; | ||||
|   info->name = real_name; | ||||
|   info->semid = semid; | ||||
|   info->fd = fd; | ||||
|   info->oflag = oflag; | ||||
|   info->wrbuf = wrbuf; | ||||
|   info->rdbuf = rdbuf; | ||||
|   info->cleanup_notify = NULL; | ||||
|   info->next = mq_hash[LOCHASH(index)]; | ||||
|   info->attr = attr; | ||||
|   mq_hash[LOCHASH(index)] = info; | ||||
|   __lock_release(mq_hash_lock); | ||||
|  | ||||
|   return (mqd_t)index; | ||||
| } | ||||
|  | ||||
| struct libc_mq * | ||||
| __find_mq (mqd_t mq) | ||||
| { | ||||
|   struct libc_mq *ptr; | ||||
|  | ||||
|   __lock_acquire(mq_hash_lock); | ||||
|  | ||||
|   ptr = mq_hash[LOCHASH((int)mq)]; | ||||
|  | ||||
|   while (ptr) | ||||
|     { | ||||
|       if (ptr->index == (int)mq) | ||||
|         break; | ||||
|       ptr = ptr->next; | ||||
|     } | ||||
|  | ||||
|   __lock_release(mq_hash_lock); | ||||
|  | ||||
|   return ptr; | ||||
| } | ||||
|        | ||||
| void | ||||
| __cleanup_mq (mqd_t mq) | ||||
| { | ||||
|   struct libc_mq *ptr; | ||||
|   struct libc_mq *prev; | ||||
|   int semid; | ||||
|   struct sembuf sb = {0, 0, 0}; | ||||
|  | ||||
|   __lock_acquire(mq_hash_lock); | ||||
|  | ||||
|   ptr = mq_hash[LOCHASH((int)mq)]; | ||||
|   prev = NULL; | ||||
|  | ||||
|   while (ptr) | ||||
|     { | ||||
|       if (ptr->index == (int)mq) | ||||
|         break; | ||||
|       prev = ptr; | ||||
|       ptr = ptr->next; | ||||
|     } | ||||
|  | ||||
|   if (ptr != NULL) | ||||
|     { | ||||
|       if (ptr->cleanup_notify != NULL) | ||||
| 	ptr->cleanup_notify (ptr); | ||||
|       if (prev != NULL) | ||||
| 	prev->next = ptr->next; | ||||
|       else | ||||
| 	mq_hash[LOCHASH((int)mq)] = NULL; | ||||
|       munmap (ptr->attr, sizeof(struct mq_attr)); | ||||
|       close (ptr->fd); | ||||
|       free (ptr->name); | ||||
|       free (ptr->wrbuf); | ||||
|       free (ptr->rdbuf); | ||||
|       semid = ptr->semid; | ||||
|       free (ptr); | ||||
|       /* lower the count of msg queue opens */ | ||||
|       sb.sem_op = -1; | ||||
|       sb.sem_num = 1; | ||||
|       sb.sem_flg = IPC_NOWAIT; | ||||
|       semop (semid, &sb, 1); | ||||
|     } | ||||
|  | ||||
|   __lock_release(mq_hash_lock); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										67
									
								
								newlib/libc/sys/linux/mq_receive.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								newlib/libc/sys/linux/mq_receive.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <mqueue.h> | ||||
| #include <fcntl.h> | ||||
| #include <errno.h> | ||||
| #include <sys/ipc.h> | ||||
| #include <sys/sem.h> | ||||
| #include <string.h> | ||||
| #define _LIBC | ||||
| #include <sys/lock.h> | ||||
| #undef _LIBC | ||||
|  | ||||
| #include "mqlocal.h" | ||||
|  | ||||
| __LOCK_INIT(static, mq_rdbuf_lock); | ||||
|  | ||||
| ssize_t | ||||
| mq_receive (mqd_t msgid, char *msg, size_t msg_len, unsigned int *msg_prio) | ||||
| { | ||||
|   struct libc_mq *info; | ||||
|   struct sembuf sb2 = {2, 1, 0}; | ||||
|   struct sembuf sb3 = {3, -1, IPC_NOWAIT}; | ||||
|   struct sembuf sb5 = {5, 1, IPC_NOWAIT}; | ||||
|   ssize_t num_bytes; | ||||
|   int ipcflag; | ||||
|  | ||||
|   info = __find_mq (msgid); | ||||
|  | ||||
|   if (info == NULL || (info->oflag & O_ACCMODE) == O_WRONLY) | ||||
|     { | ||||
|       errno = EBADF; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   if (msg_len < info->attr->mq_msgsize) | ||||
|     { | ||||
|       errno = EMSGSIZE; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   __lock_acquire (mq_rdbuf_lock); | ||||
|  | ||||
|   ipcflag = (info->attr->mq_flags & O_NONBLOCK) ? IPC_NOWAIT : 0; | ||||
|  | ||||
|   semop (info->semid, &sb5, 1); /* increase number of readers */ | ||||
|   num_bytes = msgrcv (info->msgqid, info->rdbuf, msg_len, -MQ_PRIO_MAX, ipcflag); | ||||
|   sb5.sem_op = -1; | ||||
|   semop (info->semid, &sb5, 1); /* decrease number of readers */ | ||||
|  | ||||
|   if (num_bytes != (ssize_t)-1) | ||||
|     { | ||||
|       semop (info->semid, &sb2, 1); /* add one to messages left to write */ | ||||
|       semop (info->semid, &sb3, 1); /* subtract one from messages to read */ | ||||
|       memcpy (msg, info->rdbuf->text, num_bytes); | ||||
|       if (msg_prio != NULL) | ||||
| 	*msg_prio = MQ_PRIO_MAX - info->rdbuf->type; | ||||
|     } | ||||
|    | ||||
|   __lock_release (mq_rdbuf_lock); | ||||
|   return num_bytes; | ||||
| } | ||||
|        | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										72
									
								
								newlib/libc/sys/linux/mq_send.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								newlib/libc/sys/linux/mq_send.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <mqueue.h> | ||||
| #include <fcntl.h> | ||||
| #include <errno.h> | ||||
| #include <sys/ipc.h> | ||||
| #include <sys/sem.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #define _LIBC | ||||
| #include <sys/lock.h> | ||||
| #undef _LIBC | ||||
|  | ||||
| #include "mqlocal.h" | ||||
|  | ||||
| __LOCK_INIT(static, mq_wrbuf_lock); | ||||
|  | ||||
| int | ||||
| mq_send (mqd_t msgid, const char *msg, size_t msg_len, unsigned int msg_prio) | ||||
| { | ||||
|   struct libc_mq *info; | ||||
|   struct sembuf sb2 = {2, -1, 0}; | ||||
|   struct sembuf sb3 = {3, 1, 0}; | ||||
|   int rc; | ||||
|   int ipcflag; | ||||
|  | ||||
|   info = __find_mq (msgid); | ||||
|  | ||||
|   if (info == NULL || (info->oflag & O_ACCMODE) == O_RDONLY) | ||||
|     { | ||||
|       errno = EBADF; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   if (msg_len > info->attr->mq_msgsize) | ||||
|     { | ||||
|       errno = EMSGSIZE; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   if (msg_prio > MQ_PRIO_MAX) | ||||
|     { | ||||
|       errno = EINVAL; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   __lock_acquire (mq_wrbuf_lock); | ||||
|  | ||||
|   memcpy (info->wrbuf->text, msg, msg_len); | ||||
|   info->wrbuf->type = (MQ_PRIO_MAX - msg_prio); | ||||
|  | ||||
|   ipcflag = (info->attr->mq_flags & O_NONBLOCK) ? IPC_NOWAIT : 0; | ||||
|   sb2.sem_flg = ipcflag; | ||||
|  | ||||
|   /* check to see if max msgs are on queue */ | ||||
|   rc = semop (info->semid, &sb2, 1); | ||||
|  | ||||
|   if (rc == 0) | ||||
|     rc = msgsnd (info->msgqid, info->wrbuf, msg_len, ipcflag); | ||||
|  | ||||
|   if (rc == 0) | ||||
|     semop (info->semid, &sb3, 1);  /* increment number of reads */ | ||||
|  | ||||
|   __lock_release (mq_wrbuf_lock); | ||||
|   return rc; | ||||
| } | ||||
|        | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										59
									
								
								newlib/libc/sys/linux/mq_setattr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								newlib/libc/sys/linux/mq_setattr.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <mqueue.h> | ||||
| #include <errno.h> | ||||
| #include <sys/sem.h> | ||||
| #include <string.h> | ||||
| #define _LIBC | ||||
| #include <sys/lock.h> | ||||
| #undef _LIBC | ||||
|  | ||||
| #include "mqlocal.h" | ||||
|  | ||||
| int | ||||
| mq_setattr (mqd_t msgid, const struct mq_attr *mqstat, struct mq_attr *omqstat) | ||||
| { | ||||
|   struct libc_mq *info; | ||||
|   struct sembuf sb0 = {0, -1, 0}; | ||||
|   int num_msgs; | ||||
|   int rc = 0; | ||||
|  | ||||
|   info = __find_mq (msgid); | ||||
|  | ||||
|   if (info == NULL) | ||||
|     { | ||||
|       errno = EBADF; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   /* temporarily lock message queue */ | ||||
|   semop (info->semid, &sb0, 1); | ||||
|  | ||||
|   /* make copy of old structure */ | ||||
|   if (omqstat != NULL) | ||||
|     { | ||||
|       num_msgs = semctl (info->semid, 3, GETVAL); | ||||
|       if (num_msgs >= 0) | ||||
| 	{ | ||||
| 	  memcpy (omqstat, info->attr, sizeof(struct mq_attr)); | ||||
| 	  omqstat->mq_curmsgs = num_msgs; | ||||
| 	} | ||||
|       else | ||||
| 	rc = -1; | ||||
|     } | ||||
|    | ||||
|   /* only the mq_flags field can be changed */ | ||||
|   info->attr->mq_flags = mqstat->mq_flags; | ||||
|  | ||||
|   /* release message queue */ | ||||
|   sb0.sem_op = 1; | ||||
|   semop (info->semid, &sb0, 1); | ||||
|  | ||||
|   return rc; | ||||
| } | ||||
|        | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										73
									
								
								newlib/libc/sys/linux/mq_unlink.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								newlib/libc/sys/linux/mq_unlink.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /* Copyright 2002, Red Hat Inc. */ | ||||
|  | ||||
| #include <mqueue.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/ipc.h> | ||||
| #include <sys/sem.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <machine/weakalias.h> | ||||
| #define _LIBC | ||||
| #include <sys/lock.h> | ||||
| #undef _LIBC | ||||
|  | ||||
| #include "mqlocal.h" | ||||
|  | ||||
| int | ||||
| mq_unlink (const char *name) | ||||
| { | ||||
|   int size; | ||||
|   int saved_errno; | ||||
|   char *real_name; | ||||
|   char *ptr; | ||||
|   int i, rc; | ||||
|   int semid, msgqid; | ||||
|   key_t key; | ||||
|    | ||||
|   /* ignore opening slash if present */ | ||||
|   if (*name == '/') | ||||
|     ++name;   | ||||
|   size = strlen(name); | ||||
|  | ||||
|   if ((real_name = (char *)malloc (size + sizeof(MSGQ_PREFIX))) == NULL) | ||||
|     { | ||||
|       errno = ENOSPC; | ||||
|       return -1; | ||||
|     } | ||||
|    | ||||
|   /* use given name to create shared memory file name - we convert any | ||||
|      slashes to underscores so we don't have to create directories */ | ||||
|   memcpy (real_name, MSGQ_PREFIX, sizeof(MSGQ_PREFIX) - 1); | ||||
|   memcpy (real_name + sizeof(MSGQ_PREFIX) - 1, name, size + 1); | ||||
|   ptr = real_name + sizeof(MSGQ_PREFIX) - 1; | ||||
|   for (i = 0; i < size; ++i) | ||||
|     { | ||||
|       if (*ptr == '/') | ||||
| 	*ptr = '_'; | ||||
|       ++ptr; | ||||
|     } | ||||
|  | ||||
|   /* get key and then unlink shared memory file */ | ||||
|   if ((key = ftok(real_name, 255)) == (key_t)-1) | ||||
|     return -1; | ||||
|  | ||||
|   rc = unlink (real_name); | ||||
|  | ||||
|   if (rc == 0) | ||||
|     { | ||||
|       /* try to remove semaphore and msg queues associated with shared memory file */ | ||||
|       saved_errno = errno; | ||||
|       semid = semget (key, 6, 0); | ||||
|       if (semid != -1) | ||||
| 	semctl (semid, 0, IPC_RMID); | ||||
|       msgqid = msgget (key, 0); | ||||
|       if (msgqid != -1) | ||||
| 	msgctl (msgqid, IPC_RMID, NULL); | ||||
|       errno = saved_errno; | ||||
|     } | ||||
|  | ||||
|   return rc; | ||||
| } | ||||
							
								
								
									
										47
									
								
								newlib/libc/sys/linux/mqlocal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								newlib/libc/sys/linux/mqlocal.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| /* local definitions needed by mq routines */ | ||||
|  | ||||
| #include <sys/msg.h> | ||||
| #include <signal.h> | ||||
|  | ||||
| /* a message */ | ||||
| typedef struct | ||||
| { | ||||
|   unsigned int type; | ||||
|   char text[1]; | ||||
| } MSG;  | ||||
|  | ||||
| union semun { | ||||
|   int val; | ||||
|   struct semid_ds *buf; | ||||
|   unsigned short  *array; | ||||
| } arg; | ||||
|  | ||||
| /* | ||||
|  * One of these structures is malloced to describe any open message queue | ||||
|  * each time mq_open is called.  | ||||
|  */ | ||||
|  | ||||
| struct libc_mq; | ||||
|  | ||||
| struct libc_mq { | ||||
|   int              index;          /* index of this message queue */ | ||||
|   int              msgqid;         /* value returned by msgget */ | ||||
|   int              semid;          /* semaphore id */ | ||||
|   int              fd;             /* fd of shared memory file */ | ||||
|   int              oflag;          /* original open flag used */ | ||||
|   int              th;             /* thread id for mq_notify */ | ||||
|   char            *name;           /* name used */ | ||||
|   MSG             *wrbuf;          /* msg write buffer */ | ||||
|   MSG             *rdbuf;          /* msg read buffer */ | ||||
|   struct mq_attr  *attr;           /* pointer to attribute structure */ | ||||
|   struct sigevent *sigevent;       /* used for mq_notify */ | ||||
|   void (*cleanup_notify)(struct libc_mq *); /* also used for mq_notify */ | ||||
|   struct libc_mq  *next;           /* next info struct in hash table */ | ||||
| }; | ||||
|  | ||||
| extern struct libc_mq *__find_mq (mqd_t mq); | ||||
| extern void __cleanup_mq (mqd_t mq); | ||||
| extern void __cleanup_mq_notify (struct libc_mq *ptr); | ||||
|  | ||||
| #define MSGQ_PREFIX "/dev/shm/__MSGQ__" | ||||
|  | ||||
| @@ -150,5 +150,7 @@ typedef	long	fd_mask; | ||||
| #include <linux/types.h> | ||||
| #include <bits/types.h> | ||||
| #define __mode_t_defined | ||||
| #define __gid_t_defined | ||||
| #define __uid_t_defined | ||||
|  | ||||
| #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user