summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscottc <scottc>2002-07-03 02:40:48 +0000
committerscottc <scottc>2002-07-03 02:40:48 +0000
commitd5db49380f53a4ecbf794f106c13cc63c1d6ab43 (patch)
treedc0d81d02fa7f40501022ab4111cdcf225b6808a
parenteea6a644adf1641beca7744f6f4aecc82191331e (diff)
downloadgdb-d5db49380f53a4ecbf794f106c13cc63c1d6ab43.tar.gz
* cygserver_shm.cc: Implement the ipcs(8) interfaces, IPC_INFO,
SHM_STAT and SHM_INFO. (server_shmmgr::segment_t::sequence): New static field. (server_shmmgr::segment_t::key): Remove field, use the new ds.shm_perm.key field instead. (server_shmmgr::segment_t::shmid): Remove field. (server_shmmgr::segment_t::intid): New field. (server_shmmgr::segment_t::segment_t): Use the `key' argument to initialise `ds.shm_perm.key'. Change from using `shmid' to `intid'. (server_shmmgr::_shmseg_cnt): Renamed from `_shmid_cnt'. (server_shmmgr::_intid_max): Renamed from `_shmid_max. (server_shmmgr::shmat): Move the out arguments to the start of the argument list. Rename the `pid' argument as `cygpid'. Add tracing. Pass an intid to `find ()', not a shmid. (server_shmmgr::shmctl): Add separate out arguments. Rename the `pid' argument as `cygpid'. Add support for the ipcs(8) interfaces. Add tracing. Pass an intid to `find ()', not a shmid. (server_shmmgr::shmdt): Rename the `pid' argument as `cygpid'. Add tracing. Pass an intid to `find ()', not a shmid. (server_shmmgr::shmget): Add a separate out arguments. Rename the `pid' argument as `cygpid'. Add tracing. (server_shmmgr::server_shmmgr): Update for new field names. (server_shmmgr::find_by_key): Update for the new `ds.shm_perm.key' field. (server_shmmgr::find): Update to use the new `segment_t::intid' field. (server_shmmgr::new_segment): Rename the `pid' argument as `cygpid'. Check that the requested size is within bounds. Handle new error result from `new_segment (key, HANDLE)'. (server_shmmgr::new_segment): Work with intids, not shmids. Check that the new intid is within bounds. Update for new field names. (server_shmmgr::delete_segment): Pass an intid to `find ()', not a shmid. Update for new field names. (client_request_shm::serve): Check that the incoming message length is the size of the `_parameters.in' struct, not of the whole in/out parameter union. Likewise, set the outgoing message length to the size of the `_parameters.out' struct. Update for the new server_shmmgr interfaces. * include/sys/ipc.h (ipc_perm::key): New field. * include/sys/shm.h (SHM_INFO): New constant. * cygserver_ipc.h (IPCMNI): New constant. (ipc_int2ext): Add `sequence' argument and munge this into the external ipc id. (ipc_ext2int_subsys): Unmunge the sequence number from the external ipc id. (ipc_ext2int): Ditto. (ipc_inc_id): Remove. (ipc_dec_id): Remove. * cygserver_shm.h (SHMMAX): New constant. (SHMMIN): Ditto. (SHMMNI): Ditto. (SHMSEG): Ditto. (SHMALL): Ditto. (client_request_shm::_parameters): Re-arrange as a union of two separate structs, one for in arguments, the other for out. (client_request_shm::shmid): Update for the new parameter layout. (client_request_shm::ds): Ditto. (client_request_shm::info): New method. * shm.cc (client_shmmgr::_shmat_cnt): New static field. (client_shmmgr::shmat): Add locking. Add tracing. (client_shmmgr::shmctl): Update for ipcs(8) commands. Add tracing. Add more argument checking. (client_shmmgr::shmdt): Add locking. Add tracing. Update the new `_shmat_cnt' field. (client_shmmgr::shmget): Add tracing. (client_shmmgr::fixup_shms_after_fork): Add tracing. Add consistency checking. (client_shmmgr::attach): Add more tracing. (client_shmmgr::new_segment): Update the new `_shmat_cnt' field. (client_request_shm::client_request_shm): Update for the new parameter layout. Set the outgoing message length to the size of the `_parameters.in' struct, not of the whole in/out parameter union.
-rw-r--r--winsup/cygwin/ChangeLog78
-rw-r--r--winsup/cygwin/cygserver_ipc.h77
-rwxr-xr-xwinsup/cygwin/cygserver_shm.cc337
-rw-r--r--winsup/cygwin/cygserver_shm.h87
-rw-r--r--winsup/cygwin/include/sys/ipc.h1
-rw-r--r--winsup/cygwin/include/sys/shm.h1
-rw-r--r--winsup/cygwin/shm.cc179
7 files changed, 576 insertions, 184 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c350d7a8d6e..c8720dd5b39 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,81 @@
+2002-07-03 Conrad Scott <conrad.scott@dsl.pipex.com>
+
+ * cygserver_shm.cc: Implement the ipcs(8) interfaces, IPC_INFO,
+ SHM_STAT and SHM_INFO.
+ (server_shmmgr::segment_t::sequence): New static field.
+ (server_shmmgr::segment_t::key): Remove field, use the new
+ ds.shm_perm.key field instead.
+ (server_shmmgr::segment_t::shmid): Remove field.
+ (server_shmmgr::segment_t::intid): New field.
+ (server_shmmgr::segment_t::segment_t): Use the `key' argument to
+ initialise `ds.shm_perm.key'. Change from using `shmid' to
+ `intid'.
+ (server_shmmgr::_shmseg_cnt): Renamed from `_shmid_cnt'.
+ (server_shmmgr::_intid_max): Renamed from `_shmid_max.
+ (server_shmmgr::shmat): Move the out arguments to the start of the
+ argument list. Rename the `pid' argument as `cygpid'. Add
+ tracing. Pass an intid to `find ()', not a shmid.
+ (server_shmmgr::shmctl): Add separate out arguments. Rename the
+ `pid' argument as `cygpid'. Add support for the ipcs(8)
+ interfaces. Add tracing. Pass an intid to `find ()', not a
+ shmid.
+ (server_shmmgr::shmdt): Rename the `pid' argument as `cygpid'.
+ Add tracing. Pass an intid to `find ()', not a shmid.
+ (server_shmmgr::shmget): Add a separate out arguments. Rename the
+ `pid' argument as `cygpid'. Add tracing.
+ (server_shmmgr::server_shmmgr): Update for new field names.
+ (server_shmmgr::find_by_key): Update for the new `ds.shm_perm.key'
+ field.
+ (server_shmmgr::find): Update to use the new `segment_t::intid'
+ field.
+ (server_shmmgr::new_segment): Rename the `pid' argument as
+ `cygpid'. Check that the requested size is within bounds. Handle
+ new error result from `new_segment (key, HANDLE)'.
+ (server_shmmgr::new_segment): Work with intids, not shmids. Check
+ that the new intid is within bounds. Update for new field names.
+ (server_shmmgr::delete_segment): Pass an intid to `find ()', not a
+ shmid. Update for new field names.
+ (client_request_shm::serve): Check that the incoming message
+ length is the size of the `_parameters.in' struct, not of the
+ whole in/out parameter union. Likewise, set the outgoing message
+ length to the size of the `_parameters.out' struct. Update for
+ the new server_shmmgr interfaces.
+ * include/sys/ipc.h (ipc_perm::key): New field.
+ * include/sys/shm.h (SHM_INFO): New constant.
+ * cygserver_ipc.h (IPCMNI): New constant.
+ (ipc_int2ext): Add `sequence' argument and munge this into the
+ external ipc id.
+ (ipc_ext2int_subsys): Unmunge the sequence number from the
+ external ipc id.
+ (ipc_ext2int): Ditto.
+ (ipc_inc_id): Remove.
+ (ipc_dec_id): Remove.
+ * cygserver_shm.h (SHMMAX): New constant.
+ (SHMMIN): Ditto.
+ (SHMMNI): Ditto.
+ (SHMSEG): Ditto.
+ (SHMALL): Ditto.
+ (client_request_shm::_parameters): Re-arrange as a union of two
+ separate structs, one for in arguments, the other for out.
+ (client_request_shm::shmid): Update for the new parameter layout.
+ (client_request_shm::ds): Ditto.
+ (client_request_shm::info): New method.
+ * shm.cc (client_shmmgr::_shmat_cnt): New static field.
+ (client_shmmgr::shmat): Add locking. Add tracing.
+ (client_shmmgr::shmctl): Update for ipcs(8) commands. Add
+ tracing. Add more argument checking.
+ (client_shmmgr::shmdt): Add locking. Add tracing. Update the new
+ `_shmat_cnt' field.
+ (client_shmmgr::shmget): Add tracing.
+ (client_shmmgr::fixup_shms_after_fork): Add tracing. Add
+ consistency checking.
+ (client_shmmgr::attach): Add more tracing.
+ (client_shmmgr::new_segment): Update the new `_shmat_cnt' field.
+ (client_request_shm::client_request_shm): Update for the new
+ parameter layout. Set the outgoing message length to the size of
+ the `_parameters.in' struct, not of the whole in/out parameter
+ union.
+
2002-07-02 Conrad Scott <conrad.scott@dsl.pipex.com>
* shm.cc: Remove the use of a static client_shmmgr object.
diff --git a/winsup/cygwin/cygserver_ipc.h b/winsup/cygwin/cygserver_ipc.h
index f57a4649d8c..0d0ebbc76a0 100644
--- a/winsup/cygwin/cygserver_ipc.h
+++ b/winsup/cygwin/cygserver_ipc.h
@@ -13,59 +13,72 @@ details. */
#ifndef __CYGSERVER_IPC_H__
#define __CYGSERVER_IPC_H__
+#include <assert.h>
#include <limits.h> /* For OPEN_MAX. */
/*
- * The sysv ipc id's (msgid, semid, shmid) are small integers arranged
- * such that they no subsystem will generate the same id as some other
- * subsystem, and nor do these ids overlap file descriptors (the other
- * common small integer ids). Since Cygwin can allocate more than
- * OPEN_MAX file descriptor, it can't be guarenteed not to overlap,
- * but it should help catch some errors.
+ * The sysv ipc id's (msgid, semid, shmid) are integers arranged such
+ * that they no subsystem will generate the same id as some other
+ * subsystem; nor do these ids overlap file descriptors (the other
+ * common integer ids). Since Cygwin can allocate more than OPEN_MAX
+ * file descriptors, it can't be guaranteed not to overlap, but it
+ * should help catch some errors.
*
* msgid's: OPEN_MAX, OPEN_MAX + 3, OPEN_MAX + 6, . . .
- * semid's: OPEN_MAX + 1, OPEN_MAX + 4, OPEN_MAX + 7, . . .
- * shmid's: OPEN_MAX + 2, OPEN_MAX + 5, OPEN_MAX + 8, . . .
+ * semid's: OPEN_MAX + 1, OPEN_MAX + 4, OPEN_MAX + 7, . . .
+ * shmid's: OPEN_MAX + 2, OPEN_MAX + 5, OPEN_MAX + 8, . . .
*
- * Internal ipc id's, which are 0, 1, ... within each subsystem, are
- * used solely by the ipcs(8) interface.
+ * To further ensure that ids are unique, if ipc objects are created
+ * and destroyed and then re-created, they are given new ids by
+ * munging the basic id (as above) with a sequence number.
+ *
+ * Internal ipc id's, which are 0, 1, ... within each subsystem (and
+ * not munged with a sequence number), are used solely by the ipcs(8)
+ * interface.
*/
-enum ipc_subsys_t {
- IPC_MSGOP = 0,
- IPC_SEMOP = 1,
- IPC_SHMOP = 2,
- IPC_SUBSYS_COUNT
-};
+enum ipc_subsys_t
+ {
+ IPC_MSGOP = 0,
+ IPC_SEMOP = 1,
+ IPC_SHMOP = 2,
+ IPC_SUBSYS_COUNT
+ };
-inline int
-ipc_int2ext (const int id, const ipc_subsys_t subsys)
-{
- return OPEN_MAX + (id * IPC_SUBSYS_COUNT) + subsys;
-}
+/*
+ * IPCMNI - The absolute maximum number of simultaneous ipc ids for
+ * any one subsystem.
+ */
-inline int
-ipc_ext2int (const int id)
-{
- return (id - OPEN_MAX) / IPC_SUBSYS_COUNT;
-}
+enum
+ {
+ IPCMNI = 0x10000 // Must be a power of two.
+ };
inline int
-ipc_ext2int_subsys (const int id)
+ipc_int2ext (const int intid, const ipc_subsys_t subsys, long & sequence)
{
- return (id - OPEN_MAX) % IPC_SUBSYS_COUNT;
+ assert (0 <= intid && intid < IPCMNI);
+
+ const long tmp = InterlockedIncrement (&sequence);
+
+ return (((tmp & 0x7fff) << 16)
+ | (OPEN_MAX + (intid * IPC_SUBSYS_COUNT) + subsys));
}
inline int
-ipc_inc_id (const int id, const ipc_subsys_t subsys)
+ipc_ext2int_subsys (const int extid)
{
- return id + IPC_SUBSYS_COUNT;
+ return ((extid & (IPCMNI - 1)) - OPEN_MAX) % IPC_SUBSYS_COUNT;
}
inline int
-ipc_dec_id (const int id, const ipc_subsys_t subsys)
+ipc_ext2int (const int extid, const ipc_subsys_t subsys)
{
- return id - IPC_SUBSYS_COUNT;
+ if (ipc_ext2int_subsys (extid) != subsys)
+ return -1;
+ else
+ return ((extid & (IPCMNI - 1)) - OPEN_MAX) / IPC_SUBSYS_COUNT;
}
#endif /* __CYGSERVER_IPC_H__ */
diff --git a/winsup/cygwin/cygserver_shm.cc b/winsup/cygwin/cygserver_shm.cc
index 5551494161d..ea710f37648 100755
--- a/winsup/cygwin/cygserver_shm.cc
+++ b/winsup/cygwin/cygserver_shm.cc
@@ -63,7 +63,7 @@ details. */
{ ACTION; } \
if (MSG && !LocalFree (MSG)) \
{ \
- system_printf ("failed to free memory at %p, error = %lu", \
+ system_printf ("failed to free memory at 0x%p, error = %lu", \
MSG, GetLastError ()); \
} \
SetLastError (lasterr); \
@@ -86,30 +86,39 @@ private:
// Bits for the _flg field.
enum { REMOVED = 0x01 };
- const key_t key;
+ static long sequence;
+
+ const int intid;
const int shmid;
- struct shmid_ds ds;
+ shmid_ds ds;
int flg;
const HANDLE hFileMap;
segment_t *next;
- segment_t (const key_t key, const int shmid, const HANDLE hFileMap)
- : key (key), shmid (shmid), flg (0), hFileMap (hFileMap), next (NULL)
+ segment_t (const key_t key, const int intid, const HANDLE hFileMap)
+ : intid (intid),
+ shmid (ipc_int2ext (intid, IPC_SHMOP, sequence)),
+ flg (0),
+ hFileMap (hFileMap),
+ next (NULL)
{
- bzero (&ds, sizeof (ds));
+ assert (0 <= intid && intid < SHMMNI);
+
+ memset (&ds, '\0', sizeof (ds));
+ ds.shm_perm.key = key;
}
};
public:
static server_shmmgr & instance ();
- int shmat (int shmid, int shmflg,
- pid_t, HANDLE & hFileMap,
- process_cache *, DWORD winpid);
- int shmctl (int shmid, int cmd, struct shmid_ds &, pid_t);
+ int shmat (HANDLE & hFileMap,
+ int shmid, int shmflg, pid_t, process_cache *, DWORD winpid);
+ int shmctl (int & out_shmid, shmid_ds & out_ds, shminfo & out_info,
+ const int shmid, int cmd, const shmid_ds &, pid_t);
int shmdt (int shmid, pid_t);
- int shmget (key_t, size_t, int shmflg, pid_t, uid_t, gid_t);
+ int shmget (int & out_shmid, key_t, size_t, int shmflg, pid_t, uid_t, gid_t);
private:
static server_shmmgr *_instance;
@@ -118,10 +127,10 @@ private:
static void initialise_instance ();
CRITICAL_SECTION _segments_lock;
- segment_t *_segments_head; // A list sorted by shmid.
+ segment_t *_segments_head; // A list sorted by int_id.
- int _shmid_cnt; // Number of shmid's allocated (for ipcs(8)).
- int _shmid_max; // Highest shmid yet allocated (for ipcs(8)).
+ int _shmseg_cnt; // Number of shm segments (for ipcs(8)).
+ int _intid_max; // Highest intid yet allocated (for ipcs(8)).
server_shmmgr ();
~server_shmmgr ();
@@ -131,7 +140,7 @@ private:
server_shmmgr & operator= (const server_shmmgr &);
segment_t *find_by_key (key_t);
- segment_t *find (int shmid, segment_t **previous = NULL);
+ segment_t *find (int intid, segment_t **previous = NULL);
int new_segment (key_t, size_t, int shmflg, pid_t, uid_t, gid_t);
@@ -139,6 +148,8 @@ private:
void delete_segment (segment_t *);
};
+/* static */ long server_shmmgr::segment_t::sequence = 0;
+
/* static */ server_shmmgr *server_shmmgr::_instance = NULL;
/* static */ pthread_once_t server_shmmgr::_instance_once = PTHREAD_ONCE_INIT;
@@ -161,21 +172,29 @@ server_shmmgr::instance ()
*---------------------------------------------------------------------------*/
int
-server_shmmgr::shmat (const int shmid, const int shmflg,
- const pid_t pid, HANDLE & hFileMap,
+server_shmmgr::shmat (HANDLE & hFileMap,
+ const int shmid, const int shmflg,
+ const pid_t cygpid,
process_cache *const cache, const DWORD winpid)
{
+ syscall_printf ("shmat (shmid = %d, shmflg = 0%o) for %d(%lu)",
+ shmid, shmflg, cygpid, winpid);
+
process *const client = cache->process (winpid);
if (!client)
{
+ syscall_printf (("-1 [%d] = shmat (shmid = %d, shmflg = 0%o) "
+ "for %d(%lu)"),
+ 0, EAGAIN, shmid, shmflg,
+ cygpid, winpid);
return -EAGAIN;
}
- int result;
+ int result = 0;
EnterCriticalSection (&_segments_lock);
- segment_t *const segptr = find (shmid);
+ segment_t *const segptr = find (ipc_ext2int (shmid, IPC_SHMOP));
if (!segptr)
result = -EINVAL;
@@ -189,25 +208,31 @@ server_shmmgr::shmat (const int shmid, const int shmflg,
{
with_strerr (msg,
syscall_printf (("failed to duplicate handle for client "
- "[key = %lld, shmid = %d, handle = %p]:"
+ "[key = 0x%016llx, shmid = %d, handle = 0x%x]:"
"%s"),
- segptr->key, segptr->shmid,
+ segptr->ds.shm_perm.key, segptr->shmid,
segptr->hFileMap, msg));
result = -EACCES; // FIXME
}
else
{
- segptr->ds.shm_lpid = pid;
+ segptr->ds.shm_lpid = cygpid;
segptr->ds.shm_nattch += 1;
segptr->ds.shm_atime = time (NULL); // FIXME: sub-second times.
-
- result = 0;
}
LeaveCriticalSection (&_segments_lock);
client->release ();
+
+ if (result < 0)
+ syscall_printf ("-1 [%d] = shmat (shmid = %d, shmflg = 0%o) for %d(%lu)",
+ -result, shmid, shmflg, cygpid, winpid);
+ else
+ syscall_printf ("0x%x = shmat (shmid = %d, shmflg = 0%o) for %d(%lu)",
+ hFileMap, shmid, shmflg, cygpid, winpid);
+
return result;
}
@@ -216,61 +241,100 @@ server_shmmgr::shmat (const int shmid, const int shmflg,
*---------------------------------------------------------------------------*/
int
-server_shmmgr::shmctl (const int shmid, const int cmd, struct shmid_ds & ds,
- const pid_t pid)
+server_shmmgr::shmctl (int & out_shmid, shmid_ds & out_ds, shminfo & out_info,
+ const int shmid, const int cmd, const shmid_ds & ds,
+ const pid_t cygpid)
{
- int result;
- EnterCriticalSection (&_segments_lock);
+ syscall_printf ("shmctl (shmid = %d, cmd = 0x%x) for %d",
+ shmid, cmd, cygpid);
- segment_t *const segptr = find (shmid);
+ int result = 0;
+ EnterCriticalSection (&_segments_lock);
- if (!segptr)
- result = -EINVAL;
- else
+ switch (cmd)
{
- switch (cmd)
- {
- case IPC_STAT:
- ds = segptr->ds;
- result = 0;
- break;
-
- case IPC_SET:
- segptr->ds.shm_perm.uid = ds.shm_perm.uid;
- segptr->ds.shm_perm.gid = ds.shm_perm.gid;
- segptr->ds.shm_perm.mode = ds.shm_perm.mode & 0777;
- segptr->ds.shm_lpid = pid;
- segptr->ds.shm_ctime = time (NULL); // FIXME: sub-second times.
- result = 0;
- break;
-
- case IPC_RMID:
- if (segptr->flg & segment_t::REMOVED)
- result = -EIDRM;
- else
+ case IPC_STAT:
+ case SHM_STAT: // Uses intids rather than shmids.
+ case IPC_SET:
+ case IPC_RMID:
+ {
+ int intid;
+
+ if (cmd == SHM_STAT)
+ intid = shmid;
+ else
+ intid = ipc_ext2int (shmid, IPC_SHMOP);
+
+ segment_t *const segptr = find (intid);
+
+ if (!segptr)
+ result = -EINVAL;
+ else
+ switch (cmd)
{
- segptr->flg |= segment_t::REMOVED;
- if (!segptr->ds.shm_nattch)
- delete_segment (segptr);
- result = 0;
+ case IPC_STAT:
+ out_ds = segptr->ds;
+ break;
+
+ case IPC_SET:
+ segptr->ds.shm_perm.uid = ds.shm_perm.uid;
+ segptr->ds.shm_perm.gid = ds.shm_perm.gid;
+ segptr->ds.shm_perm.mode = ds.shm_perm.mode & 0777;
+ segptr->ds.shm_lpid = cygpid;
+ segptr->ds.shm_ctime = time (NULL); // FIXME: sub-second times.
+ break;
+
+ case IPC_RMID:
+ if (segptr->flg & segment_t::REMOVED)
+ result = -EIDRM;
+ else
+ {
+ segptr->flg |= segment_t::REMOVED;
+ if (!segptr->ds.shm_nattch)
+ delete_segment (segptr);
+ }
+ break;
+
+ case SHM_STAT: // ipcs(8) i'face.
+ out_ds = segptr->ds;
+ out_shmid = segptr->shmid;
+ break;
}
- break;
+ }
+ break;
- case IPC_INFO:
- result = -EINVAL;
- break;
+ case IPC_INFO:
+ out_info.shmmax = SHMMAX;
+ out_info.shmmin = SHMMIN;
+ out_info.shmmni = SHMMNI;
+ out_info.shmseg = SHMSEG;
+ out_info.shmall = SHMALL;
+ break;
- case SHM_STAT:
- result = -EINVAL;
- break;
+ case SHM_INFO: // ipcs(8) i'face.
+ out_shmid = _intid_max;
+ break;
- default:
- result = -EINVAL;
- break;
- }
+ default:
+ result = -EINVAL;
+ break;
}
LeaveCriticalSection (&_segments_lock);
+
+ if (result < 0)
+ syscall_printf (("-1 [%d] = "
+ "shmctl (shmid = %d, cmd = 0x%x) for %d"),
+ -result,
+ shmid, cmd, cygpid);
+ else
+ syscall_printf (("%d = "
+ "shmctl (shmid = %d, cmd = 0x%x) for %d"),
+ ((cmd == SHM_STAT || cmd == SHM_INFO)
+ ? out_shmid
+ : result),
+ shmid, cmd, cygpid);
+
return result;
}
@@ -279,12 +343,15 @@ server_shmmgr::shmctl (const int shmid, const int cmd, struct shmid_ds & ds,
*---------------------------------------------------------------------------*/
int
-server_shmmgr::shmdt (const int shmid, const pid_t pid)
+server_shmmgr::shmdt (const int shmid, const pid_t cygpid)
{
- int result;
+ syscall_printf ("shmdt (shmid = %d) for %d",
+ shmid, cygpid);
+
+ int result = 0;
EnterCriticalSection (&_segments_lock);
- segment_t *const segptr = find (shmid);
+ segment_t *const segptr = find (ipc_ext2int (shmid, IPC_SHMOP));
if (!segptr)
result = -EINVAL;
@@ -292,17 +359,23 @@ server_shmmgr::shmdt (const int shmid, const pid_t pid)
{
assert (segptr->ds.shm_nattch > 0);
- segptr->ds.shm_lpid = pid;
+ segptr->ds.shm_lpid = cygpid;
segptr->ds.shm_nattch -= 1;
segptr->ds.shm_dtime = time (NULL); // FIXME: sub-second times.
if (!segptr->ds.shm_nattch && (segptr->flg & segment_t::REMOVED))
delete_segment (segptr);
-
- result = 0;
}
LeaveCriticalSection (&_segments_lock);
+
+ if (result < 0)
+ syscall_printf ("-1 [%d] = shmdt (shmid = %d) for %d",
+ -result, shmid, cygpid);
+ else
+ syscall_printf ("%d = shmdt (shmid = %d) for %d",
+ result, shmid, cygpid);
+
return result;
}
@@ -311,22 +384,27 @@ server_shmmgr::shmdt (const int shmid, const pid_t pid)
*---------------------------------------------------------------------------*/
int
-server_shmmgr::shmget (const key_t key, const size_t size, const int shmflg,
- const pid_t pid, const uid_t uid, const gid_t gid)
+server_shmmgr::shmget (int & out_shmid,
+ const key_t key, const size_t size, const int shmflg,
+ const pid_t cygpid, const uid_t uid, const gid_t gid)
{
- int result;
+ syscall_printf ("shmget (key = 0x%016llx, size = %u, shmflg = 0%o) for %d",
+ key, size, shmflg,
+ cygpid);
+
+ int result = 0;
EnterCriticalSection (&_segments_lock);
/* Does a segment already exist with that key? */
if (key == IPC_PRIVATE)
- result = new_segment (key, size, shmflg, pid, uid, gid);
+ result = new_segment (key, size, shmflg, cygpid, uid, gid);
else
{
segment_t *const segptr = find_by_key (key);
if (!segptr)
if (shmflg & IPC_CREAT)
- result = new_segment (key, size, shmflg, pid, uid, gid);
+ result = new_segment (key, size, shmflg, cygpid, uid, gid);
else
result = -ENOENT;
else if (segptr->flg & segment_t::REMOVED)
@@ -340,6 +418,28 @@ server_shmmgr::shmget (const key_t key, const size_t size, const int shmflg,
}
LeaveCriticalSection (&_segments_lock);
+
+ if (result >= 0)
+ {
+ out_shmid = result;
+ result = 0;
+ }
+
+ if (result < 0)
+ syscall_printf (("-1 [%d] = "
+ "shmget (key = 0x%016llx, size = %u, shmflg = 0%o) "
+ "for %d"),
+ -result,
+ key, size, shmflg,
+ cygpid);
+ else
+ syscall_printf (("%d = "
+ "shmget (key = 0x%016llx, size = %u, shmflg = 0%o) "
+ "for %d"),
+ out_shmid,
+ key, size, shmflg,
+ cygpid);
+
return result;
}
@@ -361,8 +461,8 @@ server_shmmgr::initialise_instance ()
server_shmmgr::server_shmmgr ()
: _segments_head (NULL),
- _shmid_cnt (0),
- _shmid_max (0)
+ _shmseg_cnt (0),
+ _intid_max (0)
{
InitializeCriticalSection (&_segments_lock);
}
@@ -384,7 +484,7 @@ server_shmmgr::segment_t *
server_shmmgr::find_by_key (const key_t key)
{
for (segment_t *segptr = _segments_head; segptr; segptr = segptr->next)
- if (segptr->key == key)
+ if (segptr->ds.shm_perm.key == key)
return segptr;
return NULL;
@@ -395,15 +495,15 @@ server_shmmgr::find_by_key (const key_t key)
*---------------------------------------------------------------------------*/
server_shmmgr::segment_t *
-server_shmmgr::find (const int shmid, segment_t **previous)
+server_shmmgr::find (const int intid, segment_t **previous)
{
if (previous)
*previous = NULL;
for (segment_t *segptr = _segments_head; segptr; segptr = segptr->next)
- if (segptr->shmid == shmid)
+ if (segptr->intid == intid)
return segptr;
- else if (segptr->shmid > shmid) // The list is sorted by shmid.
+ else if (segptr->intid > intid) // The list is sorted by intid.
return NULL;
else if (previous)
*previous = segptr;
@@ -419,10 +519,13 @@ int
server_shmmgr::new_segment (const key_t key,
const size_t size,
const int shmflg,
- const pid_t pid,
+ const pid_t cygpid,
const uid_t uid,
const gid_t gid)
{
+ if (size < SHMMIN || size > SHMMAX)
+ return -EINVAL;
+
const HANDLE hFileMap = CreateFileMapping (INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE,
0, size,
@@ -440,11 +543,17 @@ server_shmmgr::new_segment (const key_t key,
segment_t *const segptr = new_segment (key, hFileMap);
+ if (!segptr)
+ {
+ (void) CloseHandle (hFileMap);
+ return -ENOSPC;
+ }
+
segptr->ds.shm_perm.cuid = segptr->ds.shm_perm.uid = uid;
segptr->ds.shm_perm.cgid = segptr->ds.shm_perm.gid = gid;
segptr->ds.shm_perm.mode = shmflg & 0777;
segptr->ds.shm_segsz = size;
- segptr->ds.shm_cpid = pid;
+ segptr->ds.shm_cpid = cygpid;
segptr->ds.shm_ctime = time (NULL); // FIXME: sub-second times.
return segptr->shmid;
@@ -454,24 +563,31 @@ server_shmmgr::new_segment (const key_t key,
* server_shmmgr::new_segment ()
*
* Allocate a new segment for the given key and file map with the
- * lowest available shmid and insert into the segment map.
+ * lowest available intid and insert into the segment map.
*---------------------------------------------------------------------------*/
server_shmmgr::segment_t *
server_shmmgr::new_segment (const key_t key, const HANDLE hFileMap)
{
- int shmid = ipc_int2ext (0, IPC_SHMOP); // Next expected shmid value.
+ int intid = 0; // Next expected intid value.
segment_t *previous = NULL; // Insert pointer.
- // Find first unallocated shmid.
- for ( segment_t *segptr = _segments_head;
- segptr && segptr->shmid == shmid;
- segptr = segptr->next, shmid = ipc_inc_id (shmid, IPC_SHMOP))
+ // Find first unallocated intid.
+ for (segment_t *segptr = _segments_head;
+ segptr && segptr->intid == intid;
+ segptr = segptr->next, intid++)
{
previous = segptr;
}
- segment_t *const segptr = safe_new (segment_t, key, shmid, hFileMap);
+ /* By the time this condition is reached (given the default value of
+ * SHMMNI), the linear searches should all replaced by something
+ * just a *little* cleverer . . .
+ */
+ if (intid >= SHMMNI)
+ return NULL;
+
+ segment_t *const segptr = safe_new (segment_t, key, intid, hFileMap);
assert (segptr);
@@ -486,9 +602,9 @@ server_shmmgr::new_segment (const key_t key, const HANDLE hFileMap)
_segments_head = segptr;
}
- _shmid_cnt += 1;
- if (shmid > _shmid_max)
- _shmid_max = shmid;
+ _shmseg_cnt += 1;
+ if (intid > _intid_max)
+ _intid_max = intid;
return segptr;
}
@@ -506,7 +622,7 @@ server_shmmgr::delete_segment (segment_t *const segptr)
segment_t *previous = NULL;
- const segment_t *const tmp = find (segptr->shmid, &previous);
+ const segment_t *const tmp = find (segptr->intid, &previous);
assert (tmp == segptr);
assert (previous ? previous->next == segptr : _segments_head == segptr);
@@ -519,11 +635,11 @@ server_shmmgr::delete_segment (segment_t *const segptr)
if (!CloseHandle (segptr->hFileMap))
with_strerr (msg,
syscall_printf (("failed to close file map "
- "[handle = %p]: %s"),
+ "[handle = 0x%x]: %s"),
segptr->hFileMap, msg));
- assert (_shmid_cnt > 0);
- _shmid_cnt -= 1;
+ assert (_shmseg_cnt > 0);
+ _shmseg_cnt -= 1;
safe_delete (segment_t, segptr);
}
@@ -551,7 +667,7 @@ client_request_shm::serve (transport_layer_base *const conn,
assert (!error_code ());
- if (msglen () != sizeof (_parameters))
+ if (msglen () != sizeof (_parameters.in))
{
syscall_printf ("bad request body length: expecting %lu bytes, got %lu",
sizeof (_parameters), msglen ());
@@ -568,25 +684,28 @@ client_request_shm::serve (transport_layer_base *const conn,
switch (_parameters.in.shmop)
{
case SHMOP_shmget:
- result = shmmgr.shmget (_parameters.in.key, _parameters.in.size,
+ result = shmmgr.shmget (_parameters.out.shmid,
+ _parameters.in.key, _parameters.in.size,
_parameters.in.shmflg, _parameters.in.cygpid,
_parameters.in.uid, _parameters.in.gid);
- _parameters.shmid = result;
break;
case SHMOP_shmat:
- result = shmmgr.shmat (_parameters.shmid, _parameters.in.shmflg,
- _parameters.in.cygpid, _parameters.out.hFileMap,
+ result = shmmgr.shmat (_parameters.out.hFileMap,
+ _parameters.in.shmid, _parameters.in.shmflg,
+ _parameters.in.cygpid,
cache, _parameters.in.winpid);
break;
case SHMOP_shmdt:
- result = shmmgr.shmdt (_parameters.shmid, _parameters.in.cygpid);
+ result = shmmgr.shmdt (_parameters.in.shmid, _parameters.in.cygpid);
break;
case SHMOP_shmctl:
- result = shmmgr.shmctl (_parameters.shmid, _parameters.in.cmd,
- _parameters.ds, _parameters.in.cygpid);
+ result = shmmgr.shmctl (_parameters.out.shmid,
+ _parameters.out.ds, _parameters.out.info,
+ _parameters.in.shmid, _parameters.in.cmd,
+ _parameters.in.ds, _parameters.in.cygpid);
break;
}
@@ -597,4 +716,6 @@ client_request_shm::serve (transport_layer_base *const conn,
error_code (-result);
msglen (0);
}
+ else
+ msglen (sizeof (_parameters.out));
}
diff --git a/winsup/cygwin/cygserver_shm.h b/winsup/cygwin/cygserver_shm.h
index 5f04d6bebe1..b323651fbbd 100644
--- a/winsup/cygwin/cygserver_shm.h
+++ b/winsup/cygwin/cygserver_shm.h
@@ -15,14 +15,36 @@ details. */
#define __CYGSERVER_SHM_H__
#include <sys/types.h>
+#include <sys/shm.h>
#include <assert.h>
+#include <limits.h>
-#include <sys/shm.h>
+#include "cygserver_ipc.h"
#include "cygwin/cygserver.h"
/*---------------------------------------------------------------------------*
+ * Values for the shminfo entries.
+ *
+ * Nb. The values are segregated between two enums so that the `small'
+ * values aren't promoted to `unsigned long' equivalents.
+ *---------------------------------------------------------------------------*/
+
+enum
+ {
+ SHMMAX = ULONG_MAX,
+ SHMSEG = ULONG_MAX,
+ SHMALL = ULONG_MAX
+ };
+
+enum
+ {
+ SHMMIN = 1,
+ SHMMNI = IPCMNI // Must be <= IPCMNI.
+ };
+
+/*---------------------------------------------------------------------------*
* class client_request_shm
*---------------------------------------------------------------------------*/
@@ -46,7 +68,7 @@ public:
#ifdef __INSIDE_CYGWIN__
client_request_shm (int shmid, int shmflg); // shmat
- client_request_shm (int shmid, int cmd, const struct shmid_ds *); // shmctl
+ client_request_shm (int shmid, int cmd, const shmid_ds *); // shmctl
client_request_shm (int shmid); // shmdt
client_request_shm (key_t, size_t, int shmflg); // shmget
#endif
@@ -56,47 +78,54 @@ public:
int shmid () const
{
assert (!error_code ());
- return _parameters.shmid;
+ return _parameters.out.shmid;
+ }
+
+ HANDLE hFileMap () const
+ {
+ assert (!error_code ());
+ return _parameters.out.hFileMap;
}
- const struct shmid_ds & ds () const
+ const shmid_ds & ds () const
{
assert (!error_code ());
- return _parameters.ds;
+ return _parameters.out.ds;
}
- HANDLE hFileMap () const
+ const shminfo & info () const
{
assert (!error_code ());
- return _parameters.out.hFileMap;
+ return _parameters.out.info;
}
private:
- struct
+ union
{
- int shmid;
- struct shmid_ds ds;
-
- union
+ struct
{
- struct
+ shmop_t shmop;
+ key_t key;
+ size_t size;
+ int shmflg;
+ int shmid;
+ int cmd;
+ pid_t cygpid;
+ DWORD winpid;
+ uid_t uid;
+ gid_t gid;
+ shmid_ds ds;
+ } in;
+
+ struct {
+ int shmid;
+ HANDLE hFileMap;
+ union
{
- shmop_t shmop;
- key_t key;
- size_t size;
- int shmflg;
- int cmd;
- pid_t cygpid;
- DWORD winpid;
- uid_t uid;
- gid_t gid;
- } in;
-
- struct
- {
- HANDLE hFileMap;
- } out;
- };
+ shmid_ds ds;
+ shminfo info;
+ };
+ } out;
} _parameters;
#ifndef __INSIDE_CYGWIN__
diff --git a/winsup/cygwin/include/sys/ipc.h b/winsup/cygwin/include/sys/ipc.h
index b9aa7c2e661..a809fd4ec7a 100644
--- a/winsup/cygwin/include/sys/ipc.h
+++ b/winsup/cygwin/include/sys/ipc.h
@@ -28,6 +28,7 @@ struct ipc_perm {
uid_t cuid;
gid_t cgid;
mode_t mode;
+ key_t key;
};
/*
diff --git a/winsup/cygwin/include/sys/shm.h b/winsup/cygwin/include/sys/shm.h
index 190f9bad4a6..15be9e6494f 100644
--- a/winsup/cygwin/include/sys/shm.h
+++ b/winsup/cygwin/include/sys/shm.h
@@ -36,6 +36,7 @@ extern "C"
* Commands 4000-4fff are reserved for SHM_xxx.
*/
#define SHM_STAT 0x4000 /* For ipcs(8) */
+#define SHM_INFO 0x4001 /* For ipcs(8) */
typedef long int shmatt_t;
diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc
index cb3caa3d077..028310b346a 100644
--- a/winsup/cygwin/shm.cc
+++ b/winsup/cygwin/shm.cc
@@ -15,6 +15,7 @@ details. */
#include <sys/types.h>
+#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
@@ -98,7 +99,7 @@ public:
static client_shmmgr & instance ();
void *shmat (int shmid, const void *, int shmflg);
- int shmctl (int shmid, int cmd, struct shmid_ds *);
+ int shmctl (int shmid, int cmd, shmid_ds *);
int shmdt (const void *);
int shmget (key_t, size_t, int shmflg);
@@ -108,7 +109,9 @@ private:
static NO_COPY client_shmmgr *_instance;
CRITICAL_SECTION _segments_lock;
- static segment_t *_segments_head; // A list sorted by shmaddr.
+ static segment_t *_segments_head; // List of attached segs by shmaddr.
+
+ static long _shmat_cnt; // No. of attached segs; for info. only.
client_shmmgr ();
~client_shmmgr ();
@@ -126,6 +129,7 @@ private:
/* static */ NO_COPY client_shmmgr *client_shmmgr::_instance;
/* static */ client_shmmgr::segment_t *client_shmmgr::_segments_head;
+/* static */ long client_shmmgr::_shmat_cnt;
/*---------------------------------------------------------------------------*
* client_shmmgr::instance ()
@@ -151,6 +155,11 @@ client_shmmgr::shmat (const int shmid,
const void *const shmaddr,
const int shmflg)
{
+ syscall_printf ("shmat (shmid = %d, shmaddr = 0x%p, shmflg = 0%o)",
+ shmid, shmaddr, shmflg);
+
+ EnterCriticalSection (&_segments_lock);
+
HANDLE hFileMap = NULL;
void *const ptr = attach (shmid, shmaddr, shmflg, hFileMap);
@@ -158,6 +167,14 @@ client_shmmgr::shmat (const int shmid,
if (ptr)
new_segment (shmid, ptr, shmflg, hFileMap);
+ LeaveCriticalSection (&_segments_lock);
+
+ if (ptr)
+ syscall_printf ("0x%p = shmat (shmid = %d, shmaddr = 0x%p, shmflg = 0%o)",
+ ptr, shmid, shmaddr, shmflg);
+ // else
+ // See the syscall_printf in client_shmmgr::attach ().
+
return (ptr ? ptr : (void *) -1);
}
@@ -168,26 +185,94 @@ client_shmmgr::shmat (const int shmid,
int
client_shmmgr::shmctl (const int shmid,
const int cmd,
- struct shmid_ds *const buf)
+ shmid_ds *const buf)
{
- client_request_shm request (shmid, cmd, buf);
+ syscall_printf ("shmctl (shmid = %d, cmd = 0x%x, buf = 0x%p)",
+ shmid, cmd, buf);
+
+ // Check parameters and set up in parameters as required.
+
+ const shmid_ds *in_buf = NULL;
+
+ switch (cmd)
+ {
+ case IPC_SET:
+ if (__check_invalid_read_ptr_errno (buf, sizeof (shmid_ds)))
+ {
+ syscall_printf (("-1 [EFAULT] = "
+ "shmctl (shmid = %d, cmd = 0x%x, buf = 0x%p)"),
+ shmid, cmd, buf);
+ set_errno (EFAULT);
+ return -1;
+ }
+ in_buf = buf;
+ break;
+
+ case IPC_STAT:
+ case SHM_STAT:
+ if (__check_null_invalid_struct_errno (buf, sizeof (shmid_ds)))
+ {
+ syscall_printf (("-1 [EFAULT] = "
+ "shmctl (shmid = %d, cmd = 0x%x, buf = 0x%p)"),
+ shmid, cmd, buf);
+ set_errno (EFAULT);
+ return -1;
+ }
+ break;
+
+ case IPC_INFO:
+ if (__check_null_invalid_struct_errno (buf, sizeof (shminfo)))
+ {
+ syscall_printf (("-1 [EFAULT] = "
+ "shmctl (shmid = %d, cmd = 0x%x, buf = 0x%p)"),
+ shmid, cmd, buf);
+ set_errno (EFAULT);
+ return -1;
+ }
+ break;
+ }
+
+ // Create and issue the command.
+
+ client_request_shm request (shmid, cmd, in_buf);
if (request.make_request () == -1 || request.error_code ())
{
+ syscall_printf (("-1 [%d] = "
+ "shmctl (shmid = %d, cmd = 0x%x, buf = 0x%p)"),
+ request.error_code (), shmid, cmd, buf);
set_errno (request.error_code ());
return -1;
}
- // Some commands require special processing, e.g. for out parameters.
+ // Some commands require special processing for their out parameters.
+
+ int result = 0;
switch (cmd)
{
case IPC_STAT:
*buf = request.ds ();
break;
+
+ case IPC_INFO:
+ *(shminfo *) buf = request.info ();
+ break;
+
+ case SHM_STAT: // ipcs(8) i'face.
+ *buf = request.ds ();
+ result = request.shmid ();
+ break;
+
+ case SHM_INFO: // ipcs(8) i'face.
+ result = request.shmid ();
+ break;
}
- return 0;
+ syscall_printf ("%d = shmctl (shmid = %d, cmd = 0x%x, buf = 0x%p)",
+ result, shmid, cmd, buf);
+
+ return result;
}
/*---------------------------------------------------------------------------*
@@ -202,12 +287,18 @@ client_shmmgr::shmctl (const int shmid,
int
client_shmmgr::shmdt (const void *const shmaddr)
{
+ syscall_printf ("shmdt (shmaddr = 0x%p)", shmaddr);
+
+ EnterCriticalSection (&_segments_lock);
+
segment_t *previous = NULL;
segment_t *const segptr = find (shmaddr, &previous);
if (!segptr)
{
+ LeaveCriticalSection (&_segments_lock);
+ syscall_printf ("-1 [EINVAL] = shmdt (shmaddr = 0x%p)", shmaddr);
set_errno (EINVAL);
return -1;
}
@@ -219,6 +310,11 @@ client_shmmgr::shmdt (const void *const shmaddr)
else
_segments_head = segptr->next;
+ LeaveCriticalSection (&_segments_lock);
+
+ const long cnt = InterlockedDecrement (&_shmat_cnt);
+ assert (cnt >= 0);
+
if (!UnmapViewOfFile ((void *) shmaddr))
with_strerr (msg,
syscall_printf (("failed to unmap view "
@@ -246,46 +342,85 @@ client_shmmgr::shmdt (const void *const shmaddr)
delete segptr;
+ syscall_printf ("0 = shmdt (shmaddr = 0x%p)", shmaddr);
+
return 0;
}
/*---------------------------------------------------------------------------*
* client_shmmgr::shmget ()
+ *
+ * The `key = 0x%08x%08x' contortions in the tracing statements is
+ * because small_printf () doesn't support 64-bit integers.
*---------------------------------------------------------------------------*/
int
client_shmmgr::shmget (const key_t key, const size_t size, const int shmflg)
{
+ syscall_printf ("shmget (key = 0x%08x%08x, size = %u, shmflg = 0%o)",
+ (unsigned) (key >> 32), (unsigned) key, size, shmflg);
+
client_request_shm request (key, size, shmflg);
if (request.make_request () == -1 || request.error_code ())
{
+ syscall_printf (("-1 [%d] = "
+ "shmget (key = 0x%08x%08x, size = %u, shmflg = 0%o)"),
+ request.error_code (),
+ (unsigned) (key >> 32), (unsigned) key, size, shmflg);
set_errno (request.error_code ());
return -1;
}
+ syscall_printf (("%d = shmget (key = 0x%08x%08x, size = %u, shmflg = 0%o)"),
+ request.shmid (),
+ (unsigned) (key >> 32), (unsigned) key, size, shmflg);
+
return request.shmid ();
}
/*---------------------------------------------------------------------------*
* client_shmmgr::fixup_shms_after_fork ()
*
- * The hFileMap handles are non-inheritable: so the
+ * The hFileMap handles are non-inheritable: so they have to be
+ * re-acquired from cygserver.
+ *
+ * Nb. This routine need not be thread-safe as it is only called at startup.
*---------------------------------------------------------------------------*/
int
client_shmmgr::fixup_shms_after_fork ()
{
+ debug_printf ("re-attaching to shm segments: %d attached", _shmat_cnt);
+
+ {
+ int length = 0;
+ for (segment_t *segptr = _segments_head; segptr; segptr = segptr->next)
+ length += 1;
+
+ if (_shmat_cnt != length)
+ {
+ system_printf (("state inconsistent: "
+ "_shmat_cnt = %d, length of segments list = %d"),
+ _shmat_cnt, length);
+ return 1;
+ }
+ }
+
for (segment_t *segptr = _segments_head; segptr; segptr = segptr->next)
if (!attach (segptr->shmid,
segptr->shmaddr,
segptr->shmflg & ~SHM_RND,
segptr->hFileMap))
{
- system_printf ("fatal error re-attaching to shared memory segments");
+ system_printf ("fatal error re-attaching to shm segment %d",
+ segptr->shmid);
return 1;
}
+ if (_shmat_cnt)
+ debug_printf ("re-attached all %d shm segments", _shmat_cnt);
+
return 0;
}
@@ -344,6 +479,9 @@ client_shmmgr::attach (const int shmid,
if (request.make_request () == -1 || request.error_code ())
{
+ syscall_printf (("-1 [%d] = "
+ "shmat (shmid = %d, shmaddr = 0x%p, shmflg = 0%o)"),
+ request.error_code (), shmid, shmaddr, shmflg);
set_errno (request.error_code ());
return NULL;
}
@@ -444,6 +582,9 @@ client_shmmgr::new_segment (const int shmid,
_segments_head = segptr;
}
+ const long cnt = InterlockedIncrement (&_shmat_cnt);
+ assert (cnt > 0);
+
return segptr;
}
@@ -462,7 +603,7 @@ shmat (const int shmid, const void *const shmaddr, const int shmflg)
*---------------------------------------------------------------------------*/
extern "C" int
-shmctl (const int shmid, const int cmd, struct shmid_ds *const buf)
+shmctl (const int shmid, const int cmd, shmid_ds *const buf)
{
return shmmgr.shmctl (shmid, cmd, buf);
}
@@ -506,13 +647,15 @@ client_request_shm::client_request_shm (const int shmid, const int shmflg)
{
_parameters.in.shmop = SHMOP_shmat;
- _parameters.shmid = shmid;
+ _parameters.in.shmid = shmid;
_parameters.in.shmflg = shmflg;
_parameters.in.cygpid = getpid ();
_parameters.in.winpid = GetCurrentProcessId ();
_parameters.in.uid = geteuid ();
_parameters.in.gid = getegid ();
+
+ msglen (sizeof (_parameters.in));
}
/*---------------------------------------------------------------------------*
@@ -521,20 +664,22 @@ client_request_shm::client_request_shm (const int shmid, const int shmflg)
client_request_shm::client_request_shm (const int shmid,
const int cmd,
- const struct shmid_ds * const buf)
+ const shmid_ds *const buf)
: client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters))
{
_parameters.in.shmop = SHMOP_shmctl;
- _parameters.shmid = shmid;
- if (cmd == IPC_SET)
- _parameters.ds = *buf;
+ _parameters.in.shmid = shmid;
_parameters.in.cmd = cmd;
+ if (buf)
+ _parameters.in.ds = *buf;
_parameters.in.cygpid = getpid ();
_parameters.in.winpid = GetCurrentProcessId ();
_parameters.in.uid = geteuid ();
_parameters.in.gid = getegid ();
+
+ msglen (sizeof (_parameters.in));
}
/*---------------------------------------------------------------------------*
@@ -546,12 +691,14 @@ client_request_shm::client_request_shm (const int shmid)
{
_parameters.in.shmop = SHMOP_shmdt;
- _parameters.shmid = shmid;
+ _parameters.in.shmid = shmid;
_parameters.in.cygpid = getpid ();
_parameters.in.winpid = GetCurrentProcessId ();
_parameters.in.uid = geteuid ();
_parameters.in.gid = getegid ();
+
+ msglen (sizeof (_parameters.in));
}
/*---------------------------------------------------------------------------*
@@ -573,4 +720,6 @@ client_request_shm::client_request_shm (const key_t key,
_parameters.in.winpid = GetCurrentProcessId ();
_parameters.in.uid = geteuid ();
_parameters.in.gid = getegid ();
+
+ msglen (sizeof (_parameters.in));
}