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> | 2002-06-19  J"orn Rennecke <joern.rennecke@superh.com> | ||||||
|  |  | ||||||
| 	* libm/common/sf_lround.c (round): Change name to: (lround). | 	* 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/sigaction.c: New file. | ||||||
|         * libc/sys/linux/signal.c: Changed to be linux signal() function |         * libc/sys/linux/signal.c: Changed to be linux signal() function | ||||||
|         so as to override regular newlib default signal.c. |         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.am: Remove sigset.c. | ||||||
|         * libc/sys/linux/machine/i386/Makefile.in: Regenerated. |         * libc/sys/linux/machine/i386/Makefile.in: Regenerated. | ||||||
|         * libc/sys/linux/machine/i386/sigset.c: Moved to linux main directory. |         * libc/sys/linux/machine/i386/sigset.c: Moved to linux main directory. | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ LIB_SOURCES = \ | |||||||
| 	brk.c \ | 	brk.c \ | ||||||
| 	cfspeed.c \ | 	cfspeed.c \ | ||||||
| 	flockfile.c \ | 	flockfile.c \ | ||||||
|  | 	ftok.c \ | ||||||
| 	funlockfile.c \ | 	funlockfile.c \ | ||||||
| 	gethostname.c \ | 	gethostname.c \ | ||||||
| 	getoptlong.c \ | 	getoptlong.c \ | ||||||
| @@ -21,8 +22,17 @@ LIB_SOURCES = \ | |||||||
| 	inode.c \ | 	inode.c \ | ||||||
| 	io.c \ | 	io.c \ | ||||||
| 	io64.c \ | 	io64.c \ | ||||||
|  | 	ipc.c \ | ||||||
| 	linux.c \ | 	linux.c \ | ||||||
| 	mmap.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 \ | 	pread.c \ | ||||||
| 	pread64.c \ | 	pread64.c \ | ||||||
| 	process.c \ | 	process.c \ | ||||||
|   | |||||||
| @@ -110,6 +110,7 @@ LIB_SOURCES = \ | |||||||
| 	brk.c \ | 	brk.c \ | ||||||
| 	cfspeed.c \ | 	cfspeed.c \ | ||||||
| 	flockfile.c \ | 	flockfile.c \ | ||||||
|  | 	ftok.c \ | ||||||
| 	funlockfile.c \ | 	funlockfile.c \ | ||||||
| 	gethostname.c \ | 	gethostname.c \ | ||||||
| 	getoptlong.c \ | 	getoptlong.c \ | ||||||
| @@ -118,8 +119,17 @@ LIB_SOURCES = \ | |||||||
| 	inode.c \ | 	inode.c \ | ||||||
| 	io.c \ | 	io.c \ | ||||||
| 	io64.c \ | 	io64.c \ | ||||||
|  | 	ipc.c \ | ||||||
| 	linux.c \ | 	linux.c \ | ||||||
| 	mmap.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 \ | 	pread.c \ | ||||||
| 	pread64.c \ | 	pread64.c \ | ||||||
| 	process.c \ | 	process.c \ | ||||||
| @@ -186,12 +196,18 @@ DEFS = @DEFS@ -I. -I$(srcdir) | |||||||
| CPPFLAGS = @CPPFLAGS@ | CPPFLAGS = @CPPFLAGS@ | ||||||
| LIBS = @LIBS@ | LIBS = @LIBS@ | ||||||
| @USE_LIBTOOL_FALSE@lib_a_OBJECTS =  brk.$(OBJEXT) cfspeed.$(OBJEXT) \ | @USE_LIBTOOL_FALSE@lib_a_OBJECTS =  brk.$(OBJEXT) cfspeed.$(OBJEXT) \ | ||||||
| @USE_LIBTOOL_FALSE@flockfile.$(OBJEXT) funlockfile.$(OBJEXT) \ | @USE_LIBTOOL_FALSE@flockfile.$(OBJEXT) ftok.$(OBJEXT) \ | ||||||
| @USE_LIBTOOL_FALSE@gethostname.$(OBJEXT) getoptlong.$(OBJEXT) \ | @USE_LIBTOOL_FALSE@funlockfile.$(OBJEXT) gethostname.$(OBJEXT) \ | ||||||
| @USE_LIBTOOL_FALSE@getreent.$(OBJEXT) ids.$(OBJEXT) inode.$(OBJEXT) \ | @USE_LIBTOOL_FALSE@getoptlong.$(OBJEXT) getreent.$(OBJEXT) \ | ||||||
| @USE_LIBTOOL_FALSE@io.$(OBJEXT) io64.$(OBJEXT) linux.$(OBJEXT) \ | @USE_LIBTOOL_FALSE@ids.$(OBJEXT) inode.$(OBJEXT) io.$(OBJEXT) \ | ||||||
| @USE_LIBTOOL_FALSE@mmap.$(OBJEXT) pread.$(OBJEXT) pread64.$(OBJEXT) \ | @USE_LIBTOOL_FALSE@io64.$(OBJEXT) ipc.$(OBJEXT) linux.$(OBJEXT) \ | ||||||
| @USE_LIBTOOL_FALSE@process.$(OBJEXT) psignal.$(OBJEXT) pwrite.$(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@pwrite64.$(OBJEXT) raise.$(OBJEXT) \ | ||||||
| @USE_LIBTOOL_FALSE@realpath.$(OBJEXT) rename.$(OBJEXT) \ | @USE_LIBTOOL_FALSE@realpath.$(OBJEXT) rename.$(OBJEXT) \ | ||||||
| @USE_LIBTOOL_FALSE@resource.$(OBJEXT) sched.$(OBJEXT) select.$(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_DEPENDENCIES =  | ||||||
| @USE_LIBTOOL_TRUE@liblinux_la_OBJECTS =  brk.lo cfspeed.lo flockfile.lo \ | @USE_LIBTOOL_TRUE@liblinux_la_OBJECTS =  brk.lo cfspeed.lo flockfile.lo \ | ||||||
| @USE_LIBTOOL_TRUE@funlockfile.lo gethostname.lo getoptlong.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 linux.lo \ | @USE_LIBTOOL_TRUE@getreent.lo ids.lo inode.lo io.lo io64.lo ipc.lo \ | ||||||
| @USE_LIBTOOL_TRUE@mmap.lo pread.lo pread64.lo process.lo psignal.lo \ | @USE_LIBTOOL_TRUE@linux.lo mmap.lo mq_close.lo mq_getattr.lo \ | ||||||
| @USE_LIBTOOL_TRUE@pwrite.lo pwrite64.lo raise.lo realpath.lo rename.lo \ | @USE_LIBTOOL_TRUE@mq_notify.lo mq_open.lo mq_receive.lo mq_send.lo \ | ||||||
| @USE_LIBTOOL_TRUE@resource.lo sched.lo select.lo seteuid.lo shm_open.lo \ | @USE_LIBTOOL_TRUE@mq_setattr.lo mq_unlink.lo pread.lo pread64.lo \ | ||||||
| @USE_LIBTOOL_TRUE@shm_unlink.lo sig.lo sigaction.lo sigqueue.lo \ | @USE_LIBTOOL_TRUE@process.lo psignal.lo pwrite.lo pwrite64.lo raise.lo \ | ||||||
| @USE_LIBTOOL_TRUE@signal.lo siglongjmp.lo sigset.lo sigwait.lo \ | @USE_LIBTOOL_TRUE@realpath.lo rename.lo resource.lo sched.lo select.lo \ | ||||||
| @USE_LIBTOOL_TRUE@socket.lo sleep.lo stack.lo strsignal.lo sysconf.lo \ | @USE_LIBTOOL_TRUE@seteuid.lo shm_open.lo shm_unlink.lo sig.lo \ | ||||||
| @USE_LIBTOOL_TRUE@sysctl.lo systat.lo system.lo tcdrain.lo tcsendbrk.lo \ | @USE_LIBTOOL_TRUE@sigaction.lo sigqueue.lo signal.lo siglongjmp.lo \ | ||||||
| @USE_LIBTOOL_TRUE@termios.lo time.lo usleep.lo wait.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@ | CFLAGS = @CFLAGS@ | ||||||
| COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_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) | 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 <linux/types.h> | ||||||
| #include <bits/types.h> | #include <bits/types.h> | ||||||
| #define __mode_t_defined | #define __mode_t_defined | ||||||
|  | #define __gid_t_defined | ||||||
|  | #define __uid_t_defined | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user