⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shm.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* 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 theCygwin license.  Please consult the file "CYGWIN_LICENSE" fordetails. */#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 () *---------------------------------------------------------------------------*/intclient_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. *---------------------------------------------------------------------------*/intclient_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 () *---------------------------------------------------------------------------*/intclient_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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -