]> granicus.if.org Git - php/commitdiff
implement shm* similar functions
authorDaniel Beulshausen <dbeu@php.net>
Tue, 7 Aug 2001 13:06:23 +0000 (13:06 +0000)
committerDaniel Beulshausen <dbeu@php.net>
Tue, 7 Aug 2001 13:06:23 +0000 (13:06 +0000)
TSRM/tsrm_win32.c
TSRM/tsrm_win32.h

index 5dfc2d60f83fa96223cb35bbb44d05914bf0e517..daf7d606b1971592029b7cbbdd180411861740f5 100644 (file)
@@ -23,6 +23,7 @@
 #include <fcntl.h>
 #include <io.h>
 #include <process.h>
+#include <time.h>
 
 #include "TSRM.h"
 
@@ -39,15 +40,30 @@ static tsrm_win32_globals win32_globals;
 static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC)
 {
        globals->process = NULL;
+       globals->shm     = NULL;
        globals->process_size = 0;
+       globals->shm_size         = 0;
        globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
 }
 
 static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
 {
-       if (globals->process != NULL) {
+       shm_pair *ptr;
+
+       if (globals->process) {
                free(globals->process);
        }
+
+       if (globals->shm) {
+               for (ptr = globals->shm; ptr < (globals->shm + globals->shm_size); ptr++) {
+                       UnmapViewOfFile(ptr->addr);
+                       CloseHandle(ptr->segment);
+                       UnmapViewOfFile(ptr->descriptor);
+                       CloseHandle(ptr->info);
+               }
+               free(globals->shm);
+       }
+
        free(globals->comspec);
 }
 
@@ -67,10 +83,10 @@ TSRM_API void tsrm_win32_shutdown(void)
 #endif
 }
 
-static ProcessPair* process_get(FILE *stream TSRMLS_DC)
+static process_pair *process_get(FILE *stream TSRMLS_DC)
 {
-       ProcessPair* ptr;
-       ProcessPair* newptr;
+       process_pair *ptr;
+       process_pair *newptr;
        
        for (ptr = TWG(process); ptr < (TWG(process) + TWG(process_size)); ptr++) {
                if (ptr->stream == stream) {
@@ -82,7 +98,7 @@ static ProcessPair* process_get(FILE *stream TSRMLS_DC)
                return ptr;
        }
        
-       newptr = (ProcessPair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(ProcessPair));
+       newptr = (process_pair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(process_pair));
        if (newptr == NULL) {
                return NULL;
        }
@@ -93,6 +109,38 @@ static ProcessPair* process_get(FILE *stream TSRMLS_DC)
        return ptr;
 }
 
+static shm_pair *shm_get(int key, void *addr)
+{
+       shm_pair *ptr;
+       shm_pair *newptr;
+       TSRMLS_FETCH();
+       
+       for (ptr = TWG(shm); ptr < (TWG(shm) + TWG(shm_size)); ptr++) {
+               if (!ptr->descriptor) {
+                       continue;
+               }
+               if (!addr && ptr->descriptor->shm_perm.key == key) {
+                       break;
+               } else if (ptr->addr == addr) {
+                       break;
+               }
+       }
+
+       if (ptr < (TWG(shm) + TWG(shm_size))) {
+               return ptr;
+       }
+       
+       newptr = (shm_pair*)realloc((void*)TWG(shm), (TWG(shm_size)+1)*sizeof(shm_pair));
+       if (newptr == NULL) {
+               return NULL;
+       }
+       
+       TWG(shm) = newptr;
+       ptr = newptr + TWG(shm_size);
+       TWG(shm_size)++;
+       return ptr;
+}
+
 static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
        HANDLE copy, self = GetCurrentProcess();
        if (!DuplicateHandle(self, fh, self, &copy, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
@@ -110,7 +158,7 @@ TSRM_API FILE *popen(const char *command, const char *type)
        SECURITY_ATTRIBUTES security;
        HANDLE in, out;
        char *cmd;
-       ProcessPair *proc;
+       process_pair *proc;
        TSRMLS_FETCH();
 
        security.nLength                                = sizeof(SECURITY_ATTRIBUTES);
@@ -169,7 +217,7 @@ TSRM_API FILE *popen(const char *command, const char *type)
 TSRM_API int pclose(FILE *stream)
 {
        DWORD termstat = 0;
-       ProcessPair* process;
+       process_pair *process;
        TSRMLS_FETCH();
 
        if ((process = process_get(stream TSRMLS_CC)) == NULL) {
@@ -187,4 +235,125 @@ TSRM_API int pclose(FILE *stream)
        return termstat;
 }
 
+TSRM_API int shmget(int key, int size, int flags)
+{
+       shm_pair *shm;
+       char shm_segment[26], shm_info[29];
+       HANDLE shm_handle, info_handle;
+       BOOL created = FALSE;
+
+       if (size < 0) {
+               return -1;
+       }
+
+       sprintf(shm_segment, "TSRM_SHM_SEGMENT:%d", key);
+       sprintf(shm_info, "TSRM_SHM_DESCRIPTOR:%d", key);
+
+       shm_handle  = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
+       info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
+
+       if ((!shm_handle && !info_handle)) {
+               if (flags & IPC_EXCL) {
+                       return -1;
+               }
+               if (flags & IPC_CREAT) {
+                       shm_handle      = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment);
+                       info_handle     = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
+                       created         = TRUE;
+               }
+               if ((!shm_handle || !info_handle)) {
+                       return -1;
+               }
+       }
+
+       shm = shm_get(key, NULL);
+       shm->segment = shm_handle;
+       shm->info        = info_handle;
+       shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
+
+       if (created) {
+               shm->descriptor->shm_perm.key   = key;
+               shm->descriptor->shm_segsz              = size;
+               shm->descriptor->shm_ctime              = time(NULL);
+               shm->descriptor->shm_cpid               = getpid();
+               shm->descriptor->shm_perm.mode  = flags;
+
+               shm->descriptor->shm_perm.cuid  = shm->descriptor->shm_perm.cgid= 0;
+               shm->descriptor->shm_perm.gid   = shm->descriptor->shm_perm.uid = 0;
+               shm->descriptor->shm_atime              = shm->descriptor->shm_dtime    = 0;
+               shm->descriptor->shm_lpid               = shm->descriptor->shm_nattch   = 0;
+               shm->descriptor->shm_perm.mode  = shm->descriptor->shm_perm.seq = 0;
+       }
+
+       if (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz ) {
+               CloseHandle(shm->segment);
+               UnmapViewOfFile(shm->descriptor);
+               CloseHandle(shm->info);
+               return -1;
+       }
+
+       return key;
+}
+
+TSRM_API void *shmat(int key, const void *shmaddr, int flags)
+{
+       shm_pair *shm = shm_get(key, NULL);
+
+       if (!shm->segment) {
+               return (void*)-1;
+       }
+
+       shm->descriptor->shm_atime = time(NULL);
+       shm->descriptor->shm_lpid  = getpid();
+       shm->descriptor->shm_nattch++;
+
+       shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
+
+       return shm->addr;
+}
+
+TSRM_API int shmdt(const void *shmaddr)
+{
+       shm_pair *shm = shm_get(0, (void*)shmaddr);
+
+       if (!shm->segment) {
+               return -1;
+       }
+
+       shm->descriptor->shm_dtime = time(NULL);
+       shm->descriptor->shm_lpid  = getpid();
+       shm->descriptor->shm_nattch--;
+
+       return UnmapViewOfFile(shm->addr) ? 0 : -1;
+}
+
+TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf) {
+       shm_pair *shm = shm_get(key, NULL);
+
+       if (!shm->segment) {
+               return -1;
+       }
+
+       switch (cmd) {
+               case IPC_STAT:
+                       memcpy(buf, shm->descriptor, sizeof(shm->descriptor));
+                       return 0;
+
+               case IPC_SET:
+                       shm->descriptor->shm_ctime              = time(NULL);
+                       shm->descriptor->shm_perm.uid   = buf->shm_perm.uid;
+                       shm->descriptor->shm_perm.gid   = buf->shm_perm.gid;
+                       shm->descriptor->shm_perm.mode  = buf->shm_perm.mode;
+                       return 0;
+
+               case IPC_RMID:
+                       if (shm->descriptor->shm_nattch < 1) {
+                               shm->descriptor->shm_perm.key = -1;
+                       }
+                       return 0;
+
+               default:
+                       return -1;
+       }
+}
 #endif
\ No newline at end of file
index cb0978668236d4897a8a51f571e589b947a69f63..08e7c7a509ec158e952cf3051980d342773ec21d 100644 (file)
 #ifdef TSRM_WIN32
 #include <windows.h>
 
+struct ipc_perm {
+       int                     key;
+       unsigned short  uid;
+       unsigned short  gid;
+       unsigned short  cuid;
+       unsigned short  cgid;
+       unsigned short  mode;
+       unsigned short  seq;
+};
+
+struct shmid_ds {
+       struct  ipc_perm        shm_perm;
+       int                             shm_segsz;
+       time_t                  shm_atime;
+       time_t                  shm_dtime;
+       time_t                  shm_ctime;
+       unsigned short  shm_cpid;
+       unsigned short  shm_lpid;
+       short                   shm_nattch;
+};
+
+typedef struct {
+       FILE    *stream;
+       HANDLE  prochnd;
+} process_pair;
+
 typedef struct {
-       FILE *stream;
-       HANDLE prochnd;
-} ProcessPair;
+       void    *addr;
+       HANDLE  info;
+       HANDLE  segment;
+       struct  shmid_ds        *descriptor;
+} shm_pair;
 
 typedef struct {
-       ProcessPair *process;
-       int process_size;
-       char *comspec;
+       process_pair    *process;
+       shm_pair                *shm;
+       int                             process_size;
+       int                             shm_size;
+       char                    *comspec;
 } tsrm_win32_globals;
 
 #ifdef ZTS
@@ -45,9 +75,33 @@ typedef struct {
 
 #endif
 
+#define IPC_PRIVATE    0
+#define IPC_CREAT      00001000
+#define IPC_EXCL       00002000
+#define IPC_NOWAIT     00004000
+
+#define IPC_RMID       0
+#define IPC_SET                1
+#define IPC_STAT       2
+#define IPC_INFO       3
+
+#define SHM_R          PAGE_READONLY
+#define SHM_W          PAGE_READWRITE
+
+#define        SHM_RDONLY      FILE_MAP_READ
+#define        SHM_RND         FILE_MAP_WRITE
+#define        SHM_REMAP       FILE_MAP_COPY
+
+
 TSRM_API void tsrm_win32_startup(void);
 TSRM_API void tsrm_win32_shutdown(void);
-TSRM_API FILE* popen(const char *command, const char *type);
-TSRM_API int pclose(FILE* stream);
+
+TSRM_API FILE *popen(const char *command, const char *type);
+TSRM_API int pclose(FILE *stream);
+
+TSRM_API int shmget(int key, int size, int flags);
+TSRM_API void *shmat(int key, const void *shmaddr, int flags);
+TSRM_API int shmdt(const void *shmaddr);
+TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf);
 
 #endif
\ No newline at end of file