]> granicus.if.org Git - php/commitdiff
@- Added the shmop extension. It allows more general ways of shared memory
authorDerick Rethans <derick@php.net>
Sun, 1 Oct 2000 15:06:04 +0000 (15:06 +0000)
committerDerick Rethans <derick@php.net>
Sun, 1 Oct 2000 15:06:04 +0000 (15:06 +0000)
@  access. (thanks to Ilia Alshanestky <iliaa@home.com> and Slava Poliakov
@  <slavapl@mailandnews.com> (Derick)

ext/shmop/Makefile.in [new file with mode: 0644]
ext/shmop/README [new file with mode: 0644]
ext/shmop/config.m4 [new file with mode: 0644]
ext/shmop/php_shmop.h [new file with mode: 0644]
ext/shmop/setup.stub [new file with mode: 0644]
ext/shmop/shmop.c [new file with mode: 0644]

diff --git a/ext/shmop/Makefile.in b/ext/shmop/Makefile.in
new file mode 100644 (file)
index 0000000..0748ec7
--- /dev/null
@@ -0,0 +1,8 @@
+# $Id$
+
+LTLIBRARY_NAME        = libshmop.la
+LTLIBRARY_SOURCES     = shmop.c
+LTLIBRARY_SHARED_NAME = shmop.la
+LTLIBRARY_SHARED_LIBADD  = $(SHMOP_SHARED_LIBADD)
+
+include $(top_srcdir)/build/dynlib.mk
diff --git a/ext/shmop/README b/ext/shmop/README
new file mode 100644 (file)
index 0000000..8ddd407
--- /dev/null
@@ -0,0 +1,65 @@
+last update sept 3, 2000 (slavapl@mailandnews.com/iliaa@home.com)
+
+Shared Memory Operations Extention to PHP4
+
+       While developing a search deamon we needed the php based front end
+       to communicate the deamon via SHM. Now, PHP already had a shared memory
+       extention (sysvshm) written by Christian Cartus <cartus@atrior.de>,
+       unfortunatly this extention was designed with PHP only in mind, and
+       offers high level features which are extremly bothersome for basic SHM
+       we had in mind.  After spending a day trying to reverse engeener figure
+       out the format of sysvshm we decided that it would be much easier to
+       add our own extention to php for simple SHM operations, we were right :)). 
+
+the functions are:
+       
+int shm_open(int key, string flags, int mode, int size)
+       
+       key             - the key of/for the shared memory block
+       flags           - 2 flags are avalible 
+                               a for access  (sets IPC_EXCL)
+                               c for create  (sets IPC_CREATE)
+       mode            - acsess mode same as for a file (0644) for example
+       size            - size of the block in bytes
+       
+       returns an indentifier
+       
+
+char shm_read(int shmid, int start, int count)
+
+       shmid           - shmid from which to read
+       start           - offset from which to start reading
+       count           - how many bytes to read
+       
+       returns the data read
+
+int shm_write(int shmid, string data, int offset)
+
+       shmid           - shmid from which to read
+       data            - string to put into shared memory
+       offset          - offset in shm to write from
+       
+       returns bytes written
+       
+int shm_size(int shmid)
+
+       shmid           - shmid for which to return the size
+       
+       returns the size in bytes of the shm segment
+       
+       
+int shm_delete(int shmid)
+
+       marks the segment for deletion, the segment will be deleted when all processes mapping it will detach
+
+       shmid           - shmid which to mark for deletion
+       
+       returns 1 if all ok, zero on failure
+       
+int shm_close(int shmid)
+
+       shmid           - shmid which to close
+       
+       returns zero
+       
+
diff --git a/ext/shmop/config.m4 b/ext/shmop/config.m4
new file mode 100644 (file)
index 0000000..532256d
--- /dev/null
@@ -0,0 +1,8 @@
+dnl $Id$
+PHP_ARG_ENABLE(shmop, whether to enable shmop support, 
+[  --enable-shmop           Enable shmop support])
+
+if test "$PHP_SHMOP" != "no"; then
+  AC_DEFINE(HAVE_SHMOP, 1, [ ])
+  PHP_EXTENSION(shmop, $ext_shared)
+fi
diff --git a/ext/shmop/php_shmop.h b/ext/shmop/php_shmop.h
new file mode 100644 (file)
index 0000000..f3fee5c
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP version 4.0                                                      |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group                   |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Slava Poliakov (slavapl@mailandnews.com)                    |
+   |          Ilia Alshanetsky (iliaa@home.com)                           |
+   +----------------------------------------------------------------------+
+ */
+#ifndef PHP_SHMOP_H
+#define PHP_SHMOP_H
+
+#if HAVE_SHMOP
+
+extern zend_module_entry shmop_module_entry;
+#define phpext_shmop_ptr &shmop_module_entry
+
+#ifdef PHP_WIN32
+#define PHP_SHMOP_API __declspec(dllexport)
+#else
+#define PHP_SHMOP_API
+#endif
+
+PHP_MINIT_FUNCTION(shmop);
+PHP_MSHUTDOWN_FUNCTION(shmop);
+PHP_RINIT_FUNCTION(shmop);
+PHP_RSHUTDOWN_FUNCTION(shmop);
+PHP_MINFO_FUNCTION(shmop);
+
+PHP_FUNCTION(shm_open);
+PHP_FUNCTION(shm_read);
+PHP_FUNCTION(shm_close);
+PHP_FUNCTION(shm_size);
+PHP_FUNCTION(shm_write);
+PHP_FUNCTION(shm_delete);
+
+struct php_shmop
+{
+       int shmid;
+       key_t key;
+       int shmflg;
+       char *addr;
+       int size;
+};
+
+static void rsclean(struct php_shmop *shmop);
+
+typedef struct {
+       int le_shmop;
+} php_shmop_globals;
+
+#ifdef ZTS
+#define SHMOPG(v) (shmop_globals->v)
+#define SHMOPLS_FETCH() php_shmop_globals *shmop_globals = ts_resource(gd_shmop_id)
+#else
+#define SHMOPG(v) (shmop_globals.v)
+#define SHMOPLS_FETCH()
+#endif
+
+#else
+
+#define phpext_shmop_ptr NULL
+
+#endif
+
+#endif /* PHP_SHMOP_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/shmop/setup.stub b/ext/shmop/setup.stub
new file mode 100644 (file)
index 0000000..e35c532
--- /dev/null
@@ -0,0 +1,5 @@
+# $Source$
+# $Id$
+
+define_option enable-shmop 'System V shmop suppport? ' yesno no \
+'    Whether to use the System V shmop (currently only Solaris and Linux).'
diff --git a/ext/shmop/shmop.c b/ext/shmop/shmop.c
new file mode 100644 (file)
index 0000000..7234eed
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP version 4.0                                                      |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group                   |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Slava Poliakov (slavapl@mailandnews.com)                    |
+   |          Ilia Alshanetsky (iliaa@home.com)                           |
+   +----------------------------------------------------------------------+
+ */
+
+#include "php.h"
+#include "php_ini.h"
+#include "php_shmop.h"
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#if HAVE_SHMOP
+
+#ifdef ZTS
+int shmop_globals_id;
+#else
+php_shmop_globals shmop_globals;
+#endif
+
+int shm_type;
+
+/* Every user visible function must have an entry in shmop_functions[].
+*/
+function_entry shmop_functions[] = {
+       PHP_FE(shm_open, NULL)
+       PHP_FE(shm_read, NULL)
+       PHP_FE(shm_close, NULL)
+       PHP_FE(shm_size, NULL)
+       PHP_FE(shm_write, NULL)
+       PHP_FE(shm_delete, NULL)
+       {NULL, NULL, NULL}      /* Must be the last line in shmop_functions[] */
+};
+
+zend_module_entry shmop_module_entry = {
+       "shmop",
+       shmop_functions,
+       PHP_MINIT(shmop),
+       PHP_MSHUTDOWN(shmop),
+       NULL,
+       NULL,
+       PHP_MINFO(shmop),
+       STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_SHMOP
+ZEND_GET_MODULE(shmop)
+#endif
+
+PHP_MINIT_FUNCTION(shmop)
+{
+       shm_type = register_list_destructors(rsclean, NULL);
+       
+       return SUCCESS;
+}
+
+static void rsclean(struct php_shmop *shmop)
+{
+       shmdt(shmop->addr);
+       efree(shmop);
+}
+
+PHP_MSHUTDOWN_FUNCTION(shmop)
+{
+       return SUCCESS;
+}
+
+PHP_MINFO_FUNCTION(shmop)
+{
+       php_info_print_table_start();
+       php_info_print_table_header(2, "shmop support", "enabled");
+       php_info_print_table_end();
+}
+
+/* {{{ void shm_open (int key, int flags, int mode, int size)
+   shm_open - gets and attaches an shared memory segment */
+PHP_FUNCTION(shm_open)
+{
+       zval **key, **flags, **mode, **size;
+       struct php_shmop *shmop;        
+       struct shmid_ds shm;
+       int rsid;
+       int shmflg=0;
+
+       if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &key, &flags, &mode, &size) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long_ex(key);
+       convert_to_string_ex(flags);
+       convert_to_long_ex(mode);
+       convert_to_long_ex(size);
+
+       shmop = emalloc(sizeof(struct php_shmop));
+       memset(shmop, 0, sizeof(struct php_shmop));
+
+       shmop->key = (*key)->value.lval;
+       shmop->shmflg |= (*mode)->value.lval;
+
+       if (memchr((*flags)->value.str.val, 'a', (*flags)->value.str.len)) {
+               shmflg = SHM_RDONLY;
+               shmop->shmflg |= IPC_EXCL;
+       } 
+       else if (memchr((*flags)->value.str.val, 'c', (*flags)->value.str.len)) {
+               shmop->shmflg |= IPC_CREAT;
+               shmop->size = (*size)->value.lval;
+       }
+       else {
+               php_error(E_WARNING, "shmopen: access mode invalid");
+               efree(shmop);
+               RETURN_FALSE;
+       }
+
+       shmop->shmid = shmget(shmop->key, shmop->size, shmop->shmflg);
+       if (shmop->shmid == -1) {
+               php_error(E_WARNING, "shmopen: can't get the block");
+               efree(shmop);
+               RETURN_FALSE;
+       }
+
+       if (shmctl(shmop->shmid, IPC_STAT, &shm)) {
+               efree(shmop);
+               php_error(E_WARNING, "shmopen: can't get information on the block");
+               RETURN_FALSE;
+       }       
+
+       shmop->addr = shmat(shmop->shmid, 0, shmflg);
+       if (shmop->addr == (char*) -1) {
+               efree(shmop);
+               php_error(E_WARNING, "shmopen: can't attach the memory block");
+               RETURN_FALSE;
+       }
+
+       shmop->size = shm.shm_segsz;
+       
+       rsid = zend_list_insert(shmop, shm_type);
+       RETURN_LONG(rsid);
+}
+/* }}} */
+
+
+/* {{{ string shm_read (int shmid, int start, int count)
+   shm_read - reads from an shm segment */
+PHP_FUNCTION(shm_read)
+{
+       zval **shmid, **start, **count;
+       struct php_shmop *shmop;
+       int type;
+       char *startaddr;
+       int bytes;
+       char *return_string;
+
+       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &shmid, &start, &count) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long_ex(shmid);
+       convert_to_long_ex(start);
+       convert_to_long_ex(count);
+
+       shmop = zend_list_find((*shmid)->value.lval, &type);    
+
+       if (!shmop) {
+               php_error(E_WARNING, "shmread: can't find this segment");
+               RETURN_FALSE;
+       }
+
+       if ((*start)->value.lval < 0 || (*start)->value.lval > shmop->size) {
+               php_error(E_WARNING, "shmread: start is out of range");
+               RETURN_FALSE;
+       }
+
+       if (((*start)->value.lval+(*count)->value.lval) > shmop->size) {
+               php_error(E_WARNING, "shmread: count is out of range");
+               RETURN_FALSE;
+       }
+
+       if ((*count)->value.lval < 0 ){
+               php_error(E_WARNING, "shmread: count is out of range");
+               RETURN_FALSE;
+       }
+
+       startaddr = shmop->addr + (*start)->value.lval;
+       bytes = (*count)->value.lval ? (*count)->value.lval : shmop->size-(*start)->value.lval;
+
+       return_string = emalloc(bytes);
+       memcpy(return_string, startaddr, bytes);
+
+       RETURN_STRINGL(return_string, bytes, 0);
+}
+/* }}} */
+
+
+/* {{{ void shm_close (int shmid)
+   shm_close - closes a shared memory segment */
+PHP_FUNCTION(shm_close)
+{
+       zval **shmid;
+       struct php_shmop *shmop;
+       int type;
+
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &shmid) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       shmop = zend_list_find((*shmid)->value.lval, &type);
+
+       if (!shmop) {
+               php_error(E_WARNING, "shmclose: no such shmid");
+               RETURN_FALSE;
+       }
+       zend_list_delete((*shmid)->value.lval);
+
+       RETURN_LONG(0);
+}
+/* }}} */
+
+
+/* {{{ int shm_size (int shmid)
+   shm_size - returns the shm size */
+PHP_FUNCTION(shm_size)
+{
+       zval **shmid;
+       struct php_shmop *shmop;
+       int type;
+
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &shmid) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long_ex(shmid);
+
+       shmop = zend_list_find((*shmid)->value.lval, &type);
+
+       if (!shmop) {
+               php_error(E_WARNING, "shmsize: no such segment");
+               RETURN_FALSE;
+       }
+
+       RETURN_LONG(shmop->size);
+}
+/* }}} */
+
+
+/* {{{ int shm_write (int shmid, string data, int offset)
+   shm_write - writes to a shared memory segment */
+PHP_FUNCTION(shm_write)
+{
+       zval **shmid, **data, **offset;
+       struct php_shmop *shmop;
+       int type;
+       int writesize;
+
+       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &shmid, &data, &offset) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long_ex(shmid);
+       convert_to_string_ex(data);
+       convert_to_long_ex(offset);
+
+       shmop = zend_list_find((*shmid)->value.lval, &type);
+
+       if (!shmop) {
+               php_error(E_WARNING, "shmwrite: error no such segment");
+               RETURN_FALSE;
+       }
+
+       if ( (*offset)->value.lval > shmop->size ) {
+               php_error(E_WARNING, "shmwrite: offset out of range");
+               RETURN_FALSE;
+       }
+
+       writesize = ((*data)->value.str.len<shmop->size-(*offset)->value.lval) ? (*data)->value.str.len : shmop->size-(*offset)->value.lval;    
+       memcpy(shmop->addr+(*offset)->value.lval, (*data)->value.str.val, writesize);
+
+       RETURN_LONG(writesize);
+}
+/* }}} */
+
+
+/* {{{ bool shm_delete (int shmid)
+   shm_delete - mark segment for deletion */
+PHP_FUNCTION(shm_delete)
+{
+       zval **shmid;
+       struct php_shmop *shmop;
+       int type;
+
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &shmid) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long_ex(shmid);
+
+       shmop = zend_list_find((*shmid)->value.lval, &type);
+
+       if (!shmop) {
+               php_error(E_WARNING, "shmdelete: error no such segment");
+               RETURN_FALSE;
+       }
+
+       if (shmctl(shmop->shmid, IPC_RMID, NULL)) {
+               php_error(E_WARNING, "shmdelete: can't mark segment for deletion (are you the owner?)");
+               RETURN_FALSE;
+       }
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+#endif /* HAVE_SHMOP */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */