From a6df500f7daacc08cd7c66f4212cb6ab6cbe803e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 19 Nov 2003 18:50:23 +0000 Subject: * cygserver.h (client_request::request_code_t): Add CYGSERVER_REQUEST_MSG and CYGSERVER_REQUEST_SEM. (admininstrator_group_sid): Add extern declaration. * cygserver_ipc.h: Rewrite. * cygserver_msg.h: New file. * cygserver_sem.h: New file. * cygserver_shm.h: More or less rewrite. * cygwin.din: Add msgctl, msgget, msgrcv, msgsnd, semctl, semget and semop. * msg.cc: Rewrite. * safe_memory.h: Remove. * sem.cc: Rewrite. * shm.cc: Rewrite. * include/cygwin/ipc.h: Use appropriate guard. (struct ipc_perm): Add seq. (IPCID_TO_IX): New define from BSD. (IPCID_TO_SEQ): Ditto. (IXSEQ_TO_IPCID): Ditto. (IPC_R): Ditto. (IPC_W): Ditto. (IPC_M): Ditto. * include/cygwin/msg.h: Use appropriate guard. #ifdef _KERNEL all stuff not explicitely defined by SUSv3. Use signed types in structs to match types used in BSD. (msgqnum_t): Define unsigned. (msglen_t): Ditto. (struct msqid_ds): Add msg_first and msg_last. (struct msginfo): Remove msgpool. Add msgssz and msgseg. * include/cygwin/sem.h: Use appropriate guard. #ifdef _KERNEL all stuff not explicitely defined by SUSv3. Use signed types in structs to match types used in BSD. (SEM_UNDO): Define appropriately. (struct semid_ds): Add sem_base. (struct seminfo): Add semmap and semusz. (SEM_A): New define from BSD. (SEM_R): Ditto. (SEM_ALLOC): Ditto. (union semun): Define. * include/cygwin/shm.h: Use appropriate guard. #ifdef _KERNEL all stuff not explicitely defined by SUSv3. Use signed types in structs to match types used in BSD. (SHMLBA): Define using cygwin_internal(CW_GET_SHMLBA) call. (struct shmid_ds): Add shm_internal. (struct shm_info): Rename shm_ids to used_ids as in BSD. Add define for shm_ids. * include/cygwin/sysproto.h: New file. * include/cygwin/version.h: Bump API minor number. * include/sys/ipc.h: New file. * include/sys/msg.h: New file. * include/sys/queue.h: New file from BSD. * include/sys/sem.h: New file. * include/sys/shm.h: New file. * include/sys/sysproto.h: New file. --- winsup/cygwin/msg.cc | 180 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 7 deletions(-) (limited to 'winsup/cygwin/msg.cc') diff --git a/winsup/cygwin/msg.cc b/winsup/cygwin/msg.cc index fecaa068a..368708b1d 100644 --- a/winsup/cygwin/msg.cc +++ b/winsup/cygwin/msg.cc @@ -1,8 +1,6 @@ -/* msg.cc: Single unix specification IPC interface for Cygwin. +/* msg.cc: XSI IPC interface for Cygwin. - Copyright 2002 Red Hat, Inc. - - Written by Conrad Scott . + Copyright 2003 Red Hat, Inc. This file is part of Cygwin. @@ -11,37 +9,205 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" - +#include "cygerrno.h" +#ifdef USE_SERVER #include -#include +#include +#include +#include "sigproc.h" -#include "cygerrno.h" +#include "cygserver_ipc.h" +#include "cygserver_msg.h" + +/* + * client_request_msg Constructors + */ + +client_request_msg::client_request_msg (int msqid, + int cmd, + struct msqid_ds *buf) + : client_request (CYGSERVER_REQUEST_MSG, &_parameters, sizeof (_parameters)) +{ + _parameters.in.msgop = MSGOP_msgctl; + ipc_set_proc_info (_parameters.in.ipcblk); + + _parameters.in.ctlargs.msqid = msqid; + _parameters.in.ctlargs.cmd = cmd; + _parameters.in.ctlargs.buf = buf; + + msglen (sizeof (_parameters.in)); +} + +client_request_msg::client_request_msg (key_t key, + int msgflg) + : client_request (CYGSERVER_REQUEST_MSG, &_parameters, sizeof (_parameters)) +{ + _parameters.in.msgop = MSGOP_msgget; + ipc_set_proc_info (_parameters.in.ipcblk); + + _parameters.in.getargs.key = key; + _parameters.in.getargs.msgflg = msgflg; + + msglen (sizeof (_parameters.in)); +} + +client_request_msg::client_request_msg (int msqid, + void *msgp, + size_t msgsz, + long msgtyp, + int msgflg) + : client_request (CYGSERVER_REQUEST_MSG, &_parameters, sizeof (_parameters)) +{ + _parameters.in.msgop = MSGOP_msgrcv; + ipc_set_proc_info (_parameters.in.ipcblk); + + _parameters.in.rcvargs.msqid = msqid; + _parameters.in.rcvargs.msgp = msgp; + _parameters.in.rcvargs.msgsz = msgsz; + _parameters.in.rcvargs.msgtyp = msgtyp; + _parameters.in.rcvargs.msgflg = msgflg; + + msglen (sizeof (_parameters.in)); +} + +client_request_msg::client_request_msg (int msqid, + const void *msgp, + size_t msgsz, + int msgflg) + : client_request (CYGSERVER_REQUEST_MSG, &_parameters, sizeof (_parameters)) +{ + _parameters.in.msgop = MSGOP_msgsnd; + ipc_set_proc_info (_parameters.in.ipcblk); + + _parameters.in.sndargs.msqid = msqid; + _parameters.in.sndargs.msgp = msgp; + _parameters.in.sndargs.msgsz = msgsz; + _parameters.in.sndargs.msgflg = msgflg; + + msglen (sizeof (_parameters.in)); +} +#endif /* USE_SERVER */ + +/* + * XSI message queue API. These are exported by the DLL. + */ extern "C" int msgctl (int msqid, int cmd, struct msqid_ds *buf) { +#ifdef USE_SERVER + sigframe thisframe (mainthread); + syscall_printf ("msgctl (msqid = %d, cmd = 0x%x, buf = %p)", + msqid, cmd, buf); + switch (cmd) + { + case IPC_STAT: + if (__check_null_invalid_struct_errno (buf, sizeof *buf)) + return -1; + break; + case IPC_SET: + if (__check_invalid_read_ptr_errno (buf, sizeof *buf)) + return -1; + break; + case IPC_RMID: + break; + case IPC_INFO: + /* msqid == 0: Request for msginfo struct. */ + if (!msqid + && __check_null_invalid_struct_errno (buf, sizeof (struct msginfo))) + return -1; + /* Otherwise, request msqid entries from internal msqid_ds array. */ + if (msqid) + if (__check_null_invalid_struct_errno (buf, msqid * sizeof (struct msqid_ds))) + return -1; + break; + case MSG_INFO: + if (__check_null_invalid_struct_errno (buf, sizeof (struct msg_info))) + return -1; + break; + default: + syscall_printf ("-1 [%d] = msgctl ()", EINVAL); + set_errno (EINVAL); + return -1; + } + client_request_msg request (msqid, cmd, buf); + if (request.make_request () == -1 || request.retval () == -1) + { + syscall_printf ("-1 [%d] = msgctl ()", request.error_code ()); + set_errno (request.error_code ()); + return -1; + } + return request.retval (); +#else set_errno (ENOSYS); return -1; +#endif } extern "C" int msgget (key_t key, int msgflg) { +#ifdef USE_SERVER + sigframe thisframe (mainthread); + syscall_printf ("msgget (key = %U, msgflg = 0x%x)", key, msgflg); + client_request_msg request (key, msgflg); + if (request.make_request () == -1 || request.retval () == -1) + { + syscall_printf ("-1 [%d] = msgget ()", request.error_code ()); + set_errno (request.error_code ()); + return -1; + } + return request.retval (); +#else set_errno (ENOSYS); return -1; +#endif } extern "C" ssize_t msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) { +#ifdef USE_SERVER + sigframe thisframe (mainthread); + syscall_printf ("msgrcv (msqid = %d, msgp = %p, msgsz = %d, " + "msgtyp = %d, msgflg = 0x%x)", + msqid, msgp, msgsz, msgtyp, msgflg); + if (__check_null_invalid_struct_errno (msgp, msgsz)) + return -1; + client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg); + if (request.make_request () == -1 || request.rcvval () == -1) + { + syscall_printf ("-1 [%d] = msgrcv ()", request.error_code ()); + set_errno (request.error_code ()); + return -1; + } + return request.rcvval (); +#else set_errno (ENOSYS); return -1; +#endif } extern "C" int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg) { +#ifdef USE_SERVER + sigframe thisframe (mainthread); + syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %d, msgflg = 0x%x)", + msqid, msgp, msgsz, msgflg); + if (__check_invalid_read_ptr_errno (msgp, msgsz)) + return -1; + client_request_msg request (msqid, msgp, msgsz, msgflg); + if (request.make_request () == -1 || request.retval () == -1) + { + syscall_printf ("-1 [%d] = msgsnd ()", request.error_code ()); + set_errno (request.error_code ()); + return -1; + } + return request.retval (); +#else set_errno (ENOSYS); return -1; +#endif } -- cgit v1.2.3