diff options
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 } |