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/cygwin/shm.cc')
-rw-r--r--winsup/cygwin/shm.cc693
1 files changed, 0 insertions, 693 deletions
diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc
deleted file mode 100644
index 94a86e2a8..000000000
--- a/winsup/cygwin/shm.cc
+++ /dev/null
@@ -1,693 +0,0 @@
-/* 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 "winsup.h"
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "cygerrno.h"
-#include "safe_memory.h"
-#include "sigproc.h"
-
-#include "cygserver_ipc.h"
-#include "cygserver_shm.h"
-
-/*---------------------------------------------------------------------------*
- * class client_shmmgr
- *
- * A singleton class.
- *---------------------------------------------------------------------------*/
-
-#define shmmgr (client_shmmgr::instance ())
-
-class client_shmmgr
-{
-private:
- class segment_t
- {
- public:
- const int shmid;
- const void *const shmaddr;
- const int shmflg;
- HANDLE hFileMap; // Updated by fixup_shms_after_fork ().
-
- segment_t *next;
-
- segment_t (const int shmid, const void *const shmaddr, const int shmflg,
- const HANDLE hFileMap)
- : shmid (shmid), shmaddr (shmaddr), shmflg (shmflg), hFileMap (hFileMap),
- next (NULL)
- {}
- };
-
-public:
- static client_shmmgr & instance ();
-
- void *shmat (int shmid, const void *, int shmflg);
- int shmctl (int shmid, int cmd, struct shmid_ds *);
- int shmdt (const void *);
- int shmget (key_t, size_t, int shmflg);
-
- int fixup_shms_after_fork ();
-
-private:
- static NO_COPY client_shmmgr *_instance;
-
- CRITICAL_SECTION _segments_lock;
- 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 ();
-
- // Undefined (as this class is a singleton):
- client_shmmgr (const client_shmmgr &);
- client_shmmgr & operator= (const client_shmmgr &);
-
- segment_t *find (const void *, segment_t **previous = NULL);
-
- void *attach (int shmid, const void *, int shmflg, HANDLE & hFileMap);
-
- segment_t *new_segment (int shmid, const void *, int shmflg, HANDLE);
-};
-
-/* static */ NO_COPY client_shmmgr *client_shmmgr::_instance;
-
-/* The following two variables must be inherited by child processes
- * since they are used by fixup_shms_after_fork () to re-attach to the
- * parent's shm segments.
- */
-/* static */ client_shmmgr::segment_t *client_shmmgr::_segments_head;
-/* static */ long client_shmmgr::_shmat_cnt;
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::instance ()
- *---------------------------------------------------------------------------*/
-
-client_shmmgr &
-client_shmmgr::instance ()
-{
- if (!_instance)
- _instance = safe_new0 (client_shmmgr);
-
- assert (_instance);
-
- return *_instance;
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::shmat ()
- *---------------------------------------------------------------------------*/
-
-void *
-client_shmmgr::shmat (const int shmid,
- const void *const shmaddr,
- const int shmflg)
-{
- syscall_printf ("shmat (shmid = %d, shmaddr = %p, shmflg = 0%o)",
- shmid, shmaddr, shmflg);
-
- EnterCriticalSection (&_segments_lock);
-
- HANDLE hFileMap = NULL;
-
- void *const ptr = attach (shmid, shmaddr, shmflg, hFileMap);
-
- if (ptr)
- new_segment (shmid, ptr, shmflg, hFileMap);
-
- LeaveCriticalSection (&_segments_lock);
-
- if (ptr)
- syscall_printf ("%p = shmat (shmid = %d, shmaddr = %p, shmflg = 0%o)",
- ptr, shmid, shmaddr, shmflg);
- // else
- // See the syscall_printf in client_shmmgr::attach ().
-
- return (ptr ? ptr : (void *) -1);
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::shmctl ()
- *---------------------------------------------------------------------------*/
-
-int
-client_shmmgr::shmctl (const int shmid,
- const int cmd,
- struct shmid_ds *const buf)
-{
- syscall_printf ("shmctl (shmid = %d, cmd = 0x%x, buf = %p)",
- shmid, cmd, buf);
-
- // Check parameters and set up in parameters as required.
-
- const struct shmid_ds *in_buf = NULL;
-
- switch (cmd)
- {
- case IPC_SET:
- if (__check_invalid_read_ptr_errno (buf, sizeof (struct shmid_ds)))
- {
- syscall_printf (("-1 [EFAULT] = "
- "shmctl (shmid = %d, cmd = 0x%x, buf = %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 (struct shmid_ds)))
- {
- syscall_printf (("-1 [EFAULT] = "
- "shmctl (shmid = %d, cmd = 0x%x, buf = %p)"),
- shmid, cmd, buf);
- set_errno (EFAULT);
- return -1;
- }
- break;
-
- case IPC_INFO:
- if (__check_null_invalid_struct_errno (buf, sizeof (struct shminfo)))
- {
- syscall_printf (("-1 [EFAULT] = "
- "shmctl (shmid = %d, cmd = 0x%x, buf = %p)"),
- shmid, cmd, buf);
- set_errno (EFAULT);
- return -1;
- }
- break;
-
- case SHM_INFO:
- if (__check_null_invalid_struct_errno (buf, sizeof (struct shm_info)))
- {
- syscall_printf (("-1 [EFAULT] = "
- "shmctl (shmid = %d, cmd = 0x%x, buf = %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 = %p)"),
- request.error_code (), shmid, cmd, buf);
- set_errno (request.error_code ());
- return -1;
- }
-
- // Some commands require special processing for their out parameters.
-
- int result = 0;
-
- switch (cmd)
- {
- case IPC_STAT:
- *buf = request.ds ();
- break;
-
- case IPC_INFO:
- *(struct shminfo *) buf = request.shminfo ();
- break;
-
- case SHM_STAT: // ipcs(8) i'face.
- result = request.shmid ();
- *buf = request.ds ();
- break;
-
- case SHM_INFO: // ipcs(8) i'face.
- result = request.shmid ();
- *(struct shm_info *) buf = request.shm_info ();
- break;
- }
-
- syscall_printf ("%d = shmctl (shmid = %d, cmd = 0x%x, buf = %p)",
- result, shmid, cmd, buf);
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::shmdt ()
- *
- * According to Posix, the only error condition for this system call
- * is EINVAL if shmaddr is not the address of the start of an attached
- * shared memory segment. Given that, all other errors just generate
- * tracing noise.
- *---------------------------------------------------------------------------*/
-
-int
-client_shmmgr::shmdt (const void *const shmaddr)
-{
- syscall_printf ("shmdt (shmaddr = %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 = %p)", shmaddr);
- set_errno (EINVAL);
- return -1;
- }
-
- assert (previous ? previous->next == segptr : _segments_head == segptr);
-
- if (previous)
- previous->next = segptr->next;
- else
- _segments_head = segptr->next;
-
- LeaveCriticalSection (&_segments_lock);
-
- const long cnt = InterlockedDecrement (&_shmat_cnt);
- assert (cnt >= 0);
-
- if (!UnmapViewOfFile ((void *) shmaddr))
- syscall_printf (("failed to unmap view "
- "[shmid = %d, handle = %p, shmaddr = %p]:"
- "%E"),
- segptr->shmid, segptr->hFileMap, shmaddr);
-
- assert (segptr->hFileMap);
-
- if (!CloseHandle (segptr->hFileMap))
- syscall_printf (("failed to close file map handle "
- "[shmid = %d, handle = %p]: %E"),
- segptr->shmid, segptr->hFileMap);
-
- client_request_shm request (segptr->shmid);
-
- if (request.make_request () == -1 || request.error_code ())
- syscall_printf ("shmdt request failed [shmid = %d, handle = %p]: %s",
- segptr->shmid, segptr->hFileMap,
- strerror (request.error_code ()));
-
- safe_delete (segptr);
-
- syscall_printf ("0 = shmdt (shmaddr = %p)", shmaddr);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::shmget ()
- *---------------------------------------------------------------------------*/
-
-int
-client_shmmgr::shmget (const key_t key, const size_t size, const int shmflg)
-{
- syscall_printf ("shmget (key = 0x%016X, size = %u, shmflg = 0%o)",
- 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%016X, size = %u, shmflg = 0%o)"),
- request.error_code (),
- key, size, shmflg);
- set_errno (request.error_code ());
- return -1;
- }
-
- syscall_printf (("%d = shmget (key = 0x%016X, size = %u, shmflg = 0%o)"),
- request.shmid (),
- key, size, shmflg);
-
- return request.shmid ();
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::fixup_shms_after_fork ()
- *
- * 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 shm segment %d",
- segptr->shmid);
- return 1;
- }
-
- if (_shmat_cnt)
- debug_printf ("re-attached all %d shm segments", _shmat_cnt);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::client_shmmgr ()
- *---------------------------------------------------------------------------*/
-
-client_shmmgr::client_shmmgr ()
-{
- InitializeCriticalSection (&_segments_lock);
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::~client_shmmgr ()
- *---------------------------------------------------------------------------*/
-
-client_shmmgr::~client_shmmgr ()
-{
- DeleteCriticalSection (&_segments_lock);
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::find ()
- *---------------------------------------------------------------------------*/
-
-client_shmmgr::segment_t *
-client_shmmgr::find (const void *const shmaddr, segment_t **previous)
-{
- if (previous)
- *previous = NULL;
-
- for (segment_t *segptr = _segments_head; segptr; segptr = segptr->next)
- if (segptr->shmaddr == shmaddr)
- return segptr;
- else if (segptr->shmaddr > shmaddr) // The list is sorted by shmaddr.
- return NULL;
- else if (previous)
- *previous = segptr;
-
- return NULL;
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::attach ()
- *
- * The body of shmat (), also used by fixup_shms_after_fork ().
- *---------------------------------------------------------------------------*/
-
-void *
-client_shmmgr::attach (const int shmid,
- const void *shmaddr,
- const int shmflg,
- HANDLE & hFileMap)
-{
- client_request_shm request (shmid, shmflg);
-
- if (request.make_request () == -1 || request.error_code ())
- {
- syscall_printf (("-1 [%d] = "
- "shmat (shmid = %d, shmaddr = %p, shmflg = 0%o)"),
- request.error_code (), shmid, shmaddr, shmflg);
- set_errno (request.error_code ());
- return NULL;
- }
-
- int result = 0;
-
- const DWORD access = (shmflg & SHM_RDONLY) ? FILE_MAP_READ : FILE_MAP_WRITE;
-
- if (shmaddr && (shmflg & SHM_RND))
- shmaddr = (char *) shmaddr - ((ssize_t) shmaddr % SHMLBA);
-
- void *const ptr =
- MapViewOfFileEx (request.hFileMap (), access, 0, 0, 0, (void *) shmaddr);
-
- if (!ptr)
- {
- syscall_printf (("failed to map view "
- "[shmid = %d, handle = %p, shmaddr = %p]: %E"),
- shmid, request.hFileMap (), shmaddr);
- result = EINVAL; // FIXME
- }
- else if (shmaddr && ptr != shmaddr)
- {
- syscall_printf (("failed to map view at requested address "
- "[shmid = %d, handle = %p]: "
- "requested address = %p, mapped address = %p"),
- shmid, request.hFileMap (),
- shmaddr, ptr);
- result = EINVAL; // FIXME
- }
-
- if (result != 0)
- {
- if (!CloseHandle (request.hFileMap ()))
- syscall_printf (("failed to close file map handle "
- "[shmid = %d, handle = %p]: %E"),
- shmid, request.hFileMap ());
-
- client_request_shm dt_req (shmid);
-
- if (dt_req.make_request () == -1 || dt_req.error_code ())
- syscall_printf ("shmdt request failed [shmid = %d, handle = %p]: %s",
- shmid, request.hFileMap (),
- strerror (dt_req.error_code ()));
-
- set_errno (result);
- return NULL;
- }
-
- hFileMap = request.hFileMap ();
- return ptr;
-}
-
-/*---------------------------------------------------------------------------*
- * client_shmmgr::new_segment ()
- *
- * Allocate a new segment for the given shmid, file map and address
- * and insert into the segment map.
- *---------------------------------------------------------------------------*/
-
-client_shmmgr::segment_t *
-client_shmmgr::new_segment (const int shmid,
- const void *const shmaddr,
- const int shmflg,
- const HANDLE hFileMap)
-{
- assert (ipc_ext2int_subsys (shmid) == IPC_SHMOP);
- assert (hFileMap);
- assert (shmaddr);
-
- segment_t *previous = NULL; // Insert pointer.
-
- const segment_t *const tmp = find (shmaddr, &previous);
-
- assert (!tmp);
- assert (previous \
- ? (!previous->next || previous->next->shmaddr > shmaddr) \
- : (!_segments_head || _segments_head->shmaddr > shmaddr));
-
- segment_t *const segptr =
- safe_new (segment_t, shmid, shmaddr, shmflg, hFileMap);
-
- assert (segptr);
-
- if (previous)
- {
- segptr->next = previous->next;
- previous->next = segptr;
- }
- else
- {
- segptr->next = _segments_head;
- _segments_head = segptr;
- }
-
- const long cnt = InterlockedIncrement (&_shmat_cnt);
- assert (cnt > 0);
-
- return segptr;
-}
-
-/*---------------------------------------------------------------------------*
- * shmat ()
- *---------------------------------------------------------------------------*/
-
-extern "C" void *
-shmat (const int shmid, const void *const shmaddr, const int shmflg)
-{
- sigframe thisframe (mainthread);
- return shmmgr.shmat (shmid, shmaddr, shmflg);
-}
-
-/*---------------------------------------------------------------------------*
- * shmctl ()
- *---------------------------------------------------------------------------*/
-
-extern "C" int
-shmctl (const int shmid, const int cmd, struct shmid_ds *const buf)
-{
- sigframe thisframe (mainthread);
- return shmmgr.shmctl (shmid, cmd, buf);
-}
-
-/*---------------------------------------------------------------------------*
- * shmdt ()
- *---------------------------------------------------------------------------*/
-
-extern "C" int
-shmdt (const void *const shmaddr)
-{
- sigframe thisframe (mainthread);
- return shmmgr.shmdt (shmaddr);
-}
-
-/*---------------------------------------------------------------------------*
- * shmget ()
- *---------------------------------------------------------------------------*/
-
-extern "C" int
-shmget (const key_t key, const size_t size, const int shmflg)
-{
- sigframe thisframe (mainthread);
- return shmmgr.shmget (key, size, shmflg);
-}
-
-/*---------------------------------------------------------------------------*
- * fixup_shms_after_fork ()
- *---------------------------------------------------------------------------*/
-
-int __stdcall
-fixup_shms_after_fork ()
-{
- return shmmgr.fixup_shms_after_fork ();
-}
-
-/*---------------------------------------------------------------------------*
- * client_request_shm::client_request_shm ()
- *---------------------------------------------------------------------------*/
-
-client_request_shm::client_request_shm (const int shmid, const int shmflg)
- : client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters))
-{
- _parameters.in.shmop = SHMOP_shmat;
-
- _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));
-}
-
-/*---------------------------------------------------------------------------*
- * client_request_shm::client_request_shm ()
- *---------------------------------------------------------------------------*/
-
-client_request_shm::client_request_shm (const int shmid,
- const int cmd,
- const struct shmid_ds *const buf)
- : client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters))
-{
- _parameters.in.shmop = SHMOP_shmctl;
-
- _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));
-}
-
-/*---------------------------------------------------------------------------*
- * client_request_shm::client_request_shm ()
- *---------------------------------------------------------------------------*/
-
-client_request_shm::client_request_shm (const int shmid)
- : client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters))
-{
- _parameters.in.shmop = SHMOP_shmdt;
-
- _parameters.in.shmid = shmid;
-
- _parameters.in.cygpid = getpid ();
- _parameters.in.winpid = GetCurrentProcessId ();
- _parameters.in.uid = geteuid ();
- _parameters.in.gid = getegid ();
-
- msglen (sizeof (_parameters.in));
-}
-
-/*---------------------------------------------------------------------------*
- * client_request_shm::client_request_shm ()
- *---------------------------------------------------------------------------*/
-
-client_request_shm::client_request_shm (const key_t key,
- const size_t size,
- const int shmflg)
- : client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters))
-{
- _parameters.in.shmop = SHMOP_shmget;
-
- _parameters.in.key = key;
- _parameters.in.size = size;
- _parameters.in.shmflg = shmflg;
-
- _parameters.in.cygpid = getpid ();
- _parameters.in.winpid = GetCurrentProcessId ();
- _parameters.in.uid = geteuid ();
- _parameters.in.gid = getegid ();
-
- msglen (sizeof (_parameters.in));
-}