diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2003-11-19 21:50:23 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2003-11-19 21:50:23 +0300 |
commit | a6df500f7daacc08cd7c66f4212cb6ab6cbe803e (patch) | |
tree | f81a85de384145f0d97d3f717f54359b00800e3f /winsup/cygwin/msg.cc | |
parent | 282113ba894449ed17e85b296cf0760d5206ac8d (diff) |
* 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.
Diffstat (limited to 'winsup/cygwin/msg.cc')
-rw-r--r-- | winsup/cygwin/msg.cc | 180 |
1 files changed, 173 insertions, 7 deletions
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 <conrad.scott@dsl.pipex.com>. + 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 <sys/types.h> -#include <cygwin/msg.h> +#include <stdio.h> +#include <unistd.h> +#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 } |