diff options
author | Derick Rethans <derick@php.net> | 2000-10-01 15:06:04 +0000 |
---|---|---|
committer | Derick Rethans <derick@php.net> | 2000-10-01 15:06:04 +0000 |
commit | 58294f67d2ca0842d9d60fe1c26891da85201870 (patch) | |
tree | c9c28e41cef3f4f4dd853c4586de4de509a25a9b /ext/shmop | |
parent | 9ccc11ce50f5bd01fb348c56a81d5dac5a895356 (diff) | |
download | php-git-58294f67d2ca0842d9d60fe1c26891da85201870.tar.gz |
@- Added the shmop extension. It allows more general ways of shared memory
@ access. (thanks to Ilia Alshanestky <iliaa@home.com> and Slava Poliakov
@ <slavapl@mailandnews.com> (Derick)
Diffstat (limited to 'ext/shmop')
-rw-r--r-- | ext/shmop/Makefile.in | 8 | ||||
-rw-r--r-- | ext/shmop/README | 65 | ||||
-rw-r--r-- | ext/shmop/config.m4 | 8 | ||||
-rw-r--r-- | ext/shmop/php_shmop.h | 83 | ||||
-rw-r--r-- | ext/shmop/setup.stub | 5 | ||||
-rw-r--r-- | ext/shmop/shmop.c | 333 |
6 files changed, 502 insertions, 0 deletions
diff --git a/ext/shmop/Makefile.in b/ext/shmop/Makefile.in new file mode 100644 index 0000000000..0748ec799f --- /dev/null +++ b/ext/shmop/Makefile.in @@ -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 index 0000000000..8ddd407d22 --- /dev/null +++ b/ext/shmop/README @@ -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 index 0000000000..532256d9a9 --- /dev/null +++ b/ext/shmop/config.m4 @@ -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 index 0000000000..f3fee5c6f1 --- /dev/null +++ b/ext/shmop/php_shmop.h @@ -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 index 0000000000..e35c532988 --- /dev/null +++ b/ext/shmop/setup.stub @@ -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 index 0000000000..7234eed748 --- /dev/null +++ b/ext/shmop/shmop.c @@ -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: + */ |