Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygserver/shm.cc')
-rw-r--r--winsup/cygserver/shm.cc896
1 files changed, 0 insertions, 896 deletions
diff --git a/winsup/cygserver/shm.cc b/winsup/cygserver/shm.cc
deleted file mode 100644
index 90053eec2..000000000
--- a/winsup/cygserver/shm.cc
+++ /dev/null
@@ -1,896 +0,0 @@
-/* cygserver_shm.cc: Single unix specification IPC interface for Cygwin.
-
- Copyright 2002 Red Hat, Inc.
-
- Written by Conrad Scott <conrad.scott@dsl.pipex.com>.
- Based on code by Robert Collins <robert.collins@hotmail.com>.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include "woutsup.h"
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-#include "cygserver_ipc.h"
-#include "cygserver_shm.h"
-#include "security.h"
-
-#include "cygwin/cygserver.h"
-#include "cygwin/cygserver_process.h"
-#include "cygwin/cygserver_transport.h"
-
-/*---------------------------------------------------------------------------*
- * class server_shmmgr
- *
- * A singleton class.
- *---------------------------------------------------------------------------*/
-
-#define shmmgr (server_shmmgr::instance ())
-
-class server_shmmgr
-{
-private:
- class attach_t
- {
- public:
- class process *const _client;
- unsigned int _refcnt;
-
- attach_t *_next;
-
- attach_t (class process *const client)
- : _client (client),
- _refcnt (0),
- _next (NULL)
- {}
- };
-
- class segment_t
- {
- private:
- // Bits for the _flg field.
- enum { IS_DELETED = 0x01 };
-
- public:
- const int _intid;
- const int _shmid;
- struct shmid_ds _ds;
-
- segment_t *_next;
-
- segment_t (const key_t key, const int intid, const HANDLE hFileMap);
- ~segment_t ();
-
- bool is_deleted () const
- {
- return _flg & IS_DELETED;
- }
-
- bool is_pending_delete () const
- {
- return !_ds.shm_nattch && is_deleted ();
- }
-
- void mark_deleted ()
- {
- assert (!is_deleted ());
-
- _flg |= IS_DELETED;
- }
-
- int attach (class process *, HANDLE & hFileMap);
- int detach (class process *);
-
- private:
- static long _sequence;
-
- int _flg;
- const HANDLE _hFileMap;
- attach_t *_attach_head; // A list sorted by winpid;
-
- attach_t *find (const class process *, attach_t **previous = NULL);
- };
-
- class cleanup_t : public cleanup_routine
- {
- public:
- cleanup_t (const segment_t *const segptr)
- : cleanup_routine (reinterpret_cast<void *> (segptr->_shmid))
- {
- assert (key ());
- }
-
- int shmid () const { return reinterpret_cast<int> (key ()); }
-
- virtual void cleanup (class process *const client)
- {
- const int res = shmmgr.shmdt (shmid (), client);
-
- if (res != 0)
- debug_printf ("process cleanup failed [shmid = %d]: %s",
- shmid (), strerror (-res));
- }
- };
-
-public:
- static server_shmmgr & instance ();
-
- int shmat (HANDLE & hFileMap,
- int shmid, int shmflg, class process *);
- int shmctl (int & out_shmid, struct shmid_ds & out_ds,
- struct shminfo & out_shminfo, struct shm_info & out_shm_info,
- const int shmid, int cmd, const struct shmid_ds &,
- class process *);
- int shmdt (int shmid, class process *);
- int shmget (int & out_shmid, key_t, size_t, int shmflg, uid_t, gid_t,
- class process *);
-
-private:
- static server_shmmgr *_instance;
- static pthread_once_t _instance_once;
-
- static void initialise_instance ();
-
- CRITICAL_SECTION _segments_lock;
- segment_t *_segments_head; // A list sorted by int_id.
-
- int _shm_ids; // Number of shm segments (for ipcs(8)).
- int _shm_tot; // Total bytes of shm segments (for ipcs(8)).
- int _shm_atts; // Number of attached segments (for ipcs(8)).
- int _intid_max; // Highest intid yet allocated (for ipcs(8)).
-
- server_shmmgr ();
- ~server_shmmgr ();
-
- // Undefined (as this class is a singleton):
- server_shmmgr (const server_shmmgr &);
- server_shmmgr & operator= (const server_shmmgr &);
-
- segment_t *find_by_key (key_t);
- segment_t *find (int intid, segment_t **previous = NULL);
-
- int new_segment (key_t, size_t, int shmflg, pid_t, uid_t, gid_t);
-
- segment_t *new_segment (key_t, size_t, HANDLE);
- 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;
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::segment_t ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t::segment_t (const key_t key,
- const int intid,
- const HANDLE hFileMap)
- : _intid (intid),
- _shmid (ipc_int2ext (intid, IPC_SHMOP, _sequence)),
- _next (NULL),
- _flg (0),
- _hFileMap (hFileMap),
- _attach_head (NULL)
-{
- assert (0 <= _intid && _intid < SHMMNI);
-
- memset (&_ds, '\0', sizeof (_ds));
- _ds.shm_perm.key = key;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::~segment_t ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t::~segment_t ()
-{
- assert (!_attach_head);
-
- if (!CloseHandle (_hFileMap))
- syscall_printf ("failed to close file map [handle = 0x%x]: %E", _hFileMap);
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::attach ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::segment_t::attach (class process *const client,
- HANDLE & hFileMap)
-{
- assert (client);
-
- if (!DuplicateHandle (GetCurrentProcess (),
- _hFileMap,
- client->handle (),
- &hFileMap,
- 0,
- FALSE, // bInheritHandle
- DUPLICATE_SAME_ACCESS))
- {
- syscall_printf (("failed to duplicate handle for client "
- "[key = 0x%016llx, shmid = %d, handle = 0x%x]: %E"),
- _ds.shm_perm.key, _shmid, _hFileMap);
-
- return -EACCES; // FIXME: Case analysis?
- }
-
- _ds.shm_lpid = client->cygpid ();
- _ds.shm_nattch += 1;
- _ds.shm_atime = time (NULL); // FIXME: sub-second times.
-
- attach_t *previous = NULL;
- attach_t *attptr = find (client, &previous);
-
- if (!attptr)
- {
- attptr = safe_new (attach_t, client);
-
- if (previous)
- {
- attptr->_next = previous->_next;
- previous->_next = attptr;
- }
- else
- {
- attptr->_next = _attach_head;
- _attach_head = attptr;
- }
- }
-
- attptr->_refcnt += 1;
-
- cleanup_t *const cleanup = safe_new (cleanup_t, this);
-
- // FIXME: ::add should only fail if the process object is already
- // cleaning up; but it can't be doing that since this thread has it
- // locked.
-
- const bool result = client->add (cleanup);
-
- assert (result);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::detach ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::segment_t::detach (class process *const client)
-{
- attach_t *previous = NULL;
- attach_t *const attptr = find (client, &previous);
-
- if (!attptr)
- return -EINVAL;
-
- if (client->is_active ())
- {
- const cleanup_t key (this);
-
- if (!client->remove (&key))
- syscall_printf (("failed to remove cleanup routine for %d(%lu) "
- "[shmid = %d]"),
- client->cygpid (), client->winpid (),
- _shmid);
- }
-
- attptr->_refcnt -= 1;
-
- if (!attptr->_refcnt)
- {
- assert (previous ? previous->_next == attptr : _attach_head == attptr);
-
- if (previous)
- previous->_next = attptr->_next;
- else
- _attach_head = attptr->_next;
-
- safe_delete (attptr);
- }
-
- assert (_ds.shm_nattch > 0);
-
- _ds.shm_lpid = client->cygpid ();
- _ds.shm_nattch -= 1;
- _ds.shm_dtime = time (NULL); // FIXME: sub-second times.
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::find ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::attach_t *
-server_shmmgr::segment_t::find (const class process *const client,
- attach_t **previous)
-{
- if (previous)
- *previous = NULL;
-
- // Nb. The _attach_head list is sorted by winpid.
-
- for (attach_t *attptr = _attach_head; attptr; attptr = attptr->_next)
- if (attptr->_client == client)
- return attptr;
- else if (attptr->_client->winpid () > client->winpid ())
- return NULL;
- else if (previous)
- *previous = attptr;
-
- return NULL;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::instance ()
- *---------------------------------------------------------------------------*/
-
-/* static */ server_shmmgr &
-server_shmmgr::instance ()
-{
- pthread_once (&_instance_once, &initialise_instance);
-
- assert (_instance);
-
- return *_instance;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::shmat ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::shmat (HANDLE & hFileMap,
- const int shmid, const int shmflg,
- class process *const client)
-{
- syscall_printf ("shmat (shmid = %d, shmflg = 0%o) for %d(%lu)",
- shmid, shmflg, client->cygpid (), client->winpid ());
-
- int result = 0;
- EnterCriticalSection (&_segments_lock);
-
- segment_t *const segptr = find (ipc_ext2int (shmid, IPC_SHMOP));
-
- if (!segptr)
- result = -EINVAL;
- else
- result = segptr->attach (client, hFileMap);
-
- if (!result)
- _shm_atts += 1;
-
- LeaveCriticalSection (&_segments_lock);
-
- if (result < 0)
- syscall_printf (("-1 [%d] = shmat (shmid = %d, shmflg = 0%o) "
- "for %d(%lu)"),
- -result, shmid, shmflg,
- client->cygpid (), client->winpid ());
- else
- syscall_printf (("0x%x = shmat (shmid = %d, shmflg = 0%o) "
- "for %d(%lu)"),
- hFileMap, shmid, shmflg,
- client->cygpid (), client->winpid ());
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::shmctl ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::shmctl (int & out_shmid,
- struct shmid_ds & out_ds,
- struct shminfo & out_shminfo,
- struct shm_info & out_shm_info,
- const int shmid, const int cmd,
- const struct shmid_ds & ds,
- class process *const client)
-{
- syscall_printf ("shmctl (shmid = %d, cmd = 0x%x) for %d(%lu)",
- shmid, cmd, client->cygpid (), client->winpid ());
-
- int result = 0;
- EnterCriticalSection (&_segments_lock);
-
- switch (cmd)
- {
- 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)
- {
- 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 = client->cygpid ();
- segptr->_ds.shm_ctime = time (NULL); // FIXME: sub-second times.
- break;
-
- case IPC_RMID:
- if (segptr->is_deleted ())
- result = -EIDRM;
- else
- {
- segptr->mark_deleted ();
- if (segptr->is_pending_delete ())
- delete_segment (segptr);
- }
- break;
-
- case SHM_STAT: // ipcs(8) i'face.
- out_ds = segptr->_ds;
- out_shmid = segptr->_shmid;
- break;
- }
- }
- break;
-
- case IPC_INFO:
- out_shminfo.shmmax = SHMMAX;
- out_shminfo.shmmin = SHMMIN;
- out_shminfo.shmmni = SHMMNI;
- out_shminfo.shmseg = SHMSEG;
- out_shminfo.shmall = SHMALL;
- break;
-
- case SHM_INFO: // ipcs(8) i'face.
- out_shmid = _intid_max;
- out_shm_info.shm_ids = _shm_ids;
- out_shm_info.shm_tot = _shm_tot;
- out_shm_info.shm_atts = _shm_atts;
- break;
-
- default:
- result = -EINVAL;
- break;
- }
-
- LeaveCriticalSection (&_segments_lock);
-
- if (result < 0)
- syscall_printf (("-1 [%d] = "
- "shmctl (shmid = %d, cmd = 0x%x) for %d(%lu)"),
- -result,
- shmid, cmd, client->cygpid (), client->winpid ());
- else
- syscall_printf (("%d = "
- "shmctl (shmid = %d, cmd = 0x%x) for %d(%lu)"),
- ((cmd == SHM_STAT || cmd == SHM_INFO)
- ? out_shmid
- : result),
- shmid, cmd, client->cygpid (), client->winpid ());
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::shmdt ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::shmdt (const int shmid, class process *const client)
-{
- syscall_printf ("shmdt (shmid = %d) for %d(%lu)",
- shmid, client->cygpid (), client->winpid ());
-
- int result = 0;
- EnterCriticalSection (&_segments_lock);
-
- segment_t *const segptr = find (ipc_ext2int (shmid, IPC_SHMOP));
-
- if (!segptr)
- result = -EINVAL;
- else
- result = segptr->detach (client);
-
- if (!result)
- _shm_atts -= 1;
-
- if (!result && segptr->is_pending_delete ())
- delete_segment (segptr);
-
- LeaveCriticalSection (&_segments_lock);
-
- if (result < 0)
- syscall_printf ("-1 [%d] = shmdt (shmid = %d) for %d(%lu)",
- -result, shmid, client->cygpid (), client->winpid ());
- else
- syscall_printf ("%d = shmdt (shmid = %d) for %d(%lu)",
- result, shmid, client->cygpid (), client->winpid ());
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::shmget ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::shmget (int & out_shmid,
- const key_t key, const size_t size, const int shmflg,
- const uid_t uid, const gid_t gid,
- class process *const client)
-{
- syscall_printf (("shmget (key = 0x%016llx, size = %u, shmflg = 0%o) "
- "for %d(%lu)"),
- key, size, shmflg,
- client->cygpid (), client->winpid ());
-
- int result = 0;
- EnterCriticalSection (&_segments_lock);
-
- if (key == IPC_PRIVATE)
- result = new_segment (key, size, shmflg,
- client->cygpid (), uid, gid);
- else
- {
- segment_t *const segptr = find_by_key (key);
-
- if (!segptr)
- if (shmflg & IPC_CREAT)
- result = new_segment (key, size, shmflg,
- client->cygpid (), uid, gid);
- else
- result = -ENOENT;
- else if (segptr->is_deleted ())
- result = -EIDRM;
- else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL))
- result = -EEXIST;
- else if ((shmflg & ~(segptr->_ds.shm_perm.mode)) & 0777)
- result = -EACCES;
- else if (size && segptr->_ds.shm_segsz < size)
- result = -EINVAL;
- else
- result = segptr->_shmid;
- }
-
- 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(%lu)"),
- -result,
- key, size, shmflg,
- client->cygpid (), client->winpid ());
- else
- syscall_printf (("%d = "
- "shmget (key = 0x%016llx, size = %u, shmflg = 0%o) "
- "for %d(%lu)"),
- out_shmid,
- key, size, shmflg,
- client->cygpid (), client->winpid ());
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::initialise_instance ()
- *---------------------------------------------------------------------------*/
-
-/* static */ void
-server_shmmgr::initialise_instance ()
-{
- assert (!_instance);
-
- _instance = safe_new0 (server_shmmgr);
-
- assert (_instance);
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::server_shmmgr ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::server_shmmgr ()
- : _segments_head (NULL),
- _shm_ids (0),
- _shm_tot (0),
- _shm_atts (0),
- _intid_max (0)
-{
- InitializeCriticalSection (&_segments_lock);
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::~server_shmmgr ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::~server_shmmgr ()
-{
- DeleteCriticalSection (&_segments_lock);
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::find_by_key ()
- *---------------------------------------------------------------------------*/
-
-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->_ds.shm_perm.key == key)
- return segptr;
-
- return NULL;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::find ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t *
-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->_intid == intid)
- return segptr;
- else if (segptr->_intid > intid) // The list is sorted by intid.
- return NULL;
- else if (previous)
- *previous = segptr;
-
- return NULL;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::new_segment ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::new_segment (const key_t key,
- const size_t size,
- const int shmflg,
- 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,
- NULL);
-
- if (!hFileMap)
- {
- syscall_printf ("failed to create file mapping [size = %lu]: %E", size);
- return -ENOMEM; // FIXME
- }
-
- segment_t *const segptr = new_segment (key, size, 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 = cygpid;
- segptr->_ds.shm_ctime = time (NULL); // FIXME: sub-second times.
-
- return segptr->_shmid;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::new_segment ()
- *
- * Allocate a new segment for the given key and file map with the
- * lowest available intid and insert into the segment map.
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t *
-server_shmmgr::new_segment (const key_t key, const size_t size,
- const HANDLE hFileMap)
-{
- // FIXME: Overflow risk.
- if (_shm_tot + size > SHMALL)
- return NULL;
-
- int intid = 0; // Next expected intid value.
- segment_t *previous = NULL; // Insert pointer.
-
- // Find first unallocated intid.
- for (segment_t *segptr = _segments_head;
- segptr && segptr->_intid == intid;
- segptr = segptr->_next, intid++)
- {
- previous = segptr;
- }
-
- /* 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);
-
- if (previous)
- {
- segptr->_next = previous->_next;
- previous->_next = segptr;
- }
- else
- {
- segptr->_next = _segments_head;
- _segments_head = segptr;
- }
-
- _shm_ids += 1;
- _shm_tot += size;
- if (intid > _intid_max)
- _intid_max = intid;
-
- return segptr;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::delete_segment ()
- *---------------------------------------------------------------------------*/
-
-void
-server_shmmgr::delete_segment (segment_t *const segptr)
-{
- assert (segptr);
- assert (segptr->is_pending_delete ());
-
- segment_t *previous = NULL;
-
- const segment_t *const tmp = find (segptr->_intid, &previous);
-
- assert (tmp == segptr);
- assert (previous ? previous->_next == segptr : _segments_head == segptr);
-
- if (previous)
- previous->_next = segptr->_next;
- else
- _segments_head = segptr->_next;
-
- assert (_shm_ids > 0);
- _shm_ids -= 1;
- _shm_tot -= segptr->_ds.shm_segsz;
-
- safe_delete (segptr);
-}
-
-/*---------------------------------------------------------------------------*
- * client_request_shm::client_request_shm ()
- *---------------------------------------------------------------------------*/
-
-client_request_shm::client_request_shm ()
- : client_request (CYGSERVER_REQUEST_SHM,
- &_parameters, sizeof (_parameters))
-{
- // verbose: syscall_printf ("created");
-}
-
-/*---------------------------------------------------------------------------*
- * client_request_shm::serve ()
- *---------------------------------------------------------------------------*/
-
-void
-client_request_shm::serve (transport_layer_base *const conn,
- process_cache *const cache)
-{
- assert (conn);
-
- assert (!error_code ());
-
- if (msglen () != sizeof (_parameters.in))
- {
- syscall_printf ("bad request body length: expecting %lu bytes, got %lu",
- sizeof (_parameters), msglen ());
- error_code (EINVAL);
- msglen (0);
- return;
- }
-
- // FIXME: Get a return code out of this and don't continue on error.
- conn->impersonate_client ();
-
- class process *const client = cache->process (_parameters.in.cygpid,
- _parameters.in.winpid);
-
- if (!client)
- {
- error_code (EAGAIN);
- msglen (0);
- return;
- }
-
- int result = -EINVAL;
-
- switch (_parameters.in.shmop)
- {
- case SHMOP_shmget:
- result = shmmgr.shmget (_parameters.out.shmid,
- _parameters.in.key, _parameters.in.size,
- _parameters.in.shmflg,
- _parameters.in.uid, _parameters.in.gid,
- client);
- break;
-
- case SHMOP_shmat:
- result = shmmgr.shmat (_parameters.out.hFileMap,
- _parameters.in.shmid, _parameters.in.shmflg,
- client);
- break;
-
- case SHMOP_shmdt:
- result = shmmgr.shmdt (_parameters.in.shmid, client);
- break;
-
- case SHMOP_shmctl:
- result = shmmgr.shmctl (_parameters.out.shmid,
- _parameters.out.ds, _parameters.out.shminfo,
- _parameters.out.shm_info,
- _parameters.in.shmid, _parameters.in.cmd,
- _parameters.in.ds,
- client);
- break;
- }
-
- client->release ();
- conn->revert_to_self ();
-
- if (result < 0)
- {
- error_code (-result);
- msglen (0);
- }
- else
- msglen (sizeof (_parameters.out));
-}