diff --git a/ext/sysvshm/php_sysvshm.h b/ext/sysvshm/php_sysvshm.h index 280b3e487caed..fcaa878b48c5f 100644 --- a/ext/sysvshm/php_sysvshm.h +++ b/ext/sysvshm/php_sysvshm.h @@ -26,9 +26,11 @@ extern zend_module_entry sysvshm_module_entry; #define sysvshm_module_ptr &sysvshm_module_entry +#include #include #include #include +#include #define PHP_SHM_RSRC_NAME "sysvshm" @@ -58,6 +60,13 @@ typedef struct { sysvshm_chunk_head *ptr; /* memory address of shared memory */ } sysvshm_shm; +typedef struct { + char *gr_name; /* group name */ + char *gr_passwd; /* group password */ + gid_t gr_gid; /* group ID */ + char **gr_mem; /* group members */ +} group; + PHP_MINIT_FUNCTION(sysvshm); PHP_FUNCTION(shm_attach); PHP_FUNCTION(shm_detach); diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 2d4f66aead096..013a485e771bc 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -44,6 +44,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_attach, 0, 0, 1) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, memsize) ZEND_ARG_INFO(0, perm) + ZEND_ARG_INFO(0, grp) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_detach, 0, 0, 1) @@ -149,8 +150,12 @@ PHP_FUNCTION(shm_attach) { sysvshm_shm *shm_list_ptr; char *shm_ptr; + char *group_name = NULL; + int grp_len; sysvshm_chunk_head *chunk_ptr; long shm_key, shm_id, shm_size = php_sysvshm.init_mem, shm_flag = 0666; + struct group *group_info; + struct shmid_ds shm_info; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &shm_key, &shm_size, &shm_flag)) { return; @@ -177,6 +182,31 @@ PHP_FUNCTION(shm_attach) } } + if ( group_name != NULL ) { + if (shmctl(shm_id, IPC_STAT, &shm_info) == -1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to stat SHM id %ld: %s", shm_id, strerror(errno)); + efree(shm_list_ptr); + RETURN_FALSE; + } + + group_info = emalloc(sizeof(group)); + if ( !(group_info = getgrnam(group_name)) ) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to get group ID for group %s: %s", group_name, strerror(errno)); + efree(group_info); + efree(shm_list_ptr); + RETURN_FALSE; + } + + shm_info.shm_perm.gid = group_info->gr_gid; + efree(group_info); + + if (shmctl(shm_id, IPC_SET, &shm_info) == -1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to set group to SHM id %ld: %s", shm_id, strerror(errno)); + efree(shm_list_ptr); + RETURN_FALSE; + } + } + if ((shm_ptr = shmat(shm_id, NULL, 0)) == (void *) -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%lx: %s", shm_key, strerror(errno)); efree(shm_list_ptr); diff --git a/ext/sysvshm/tests/002.phpt b/ext/sysvshm/tests/002.phpt index 61174c6b8398c..d11b9312ca264 100644 --- a/ext/sysvshm/tests/002.phpt +++ b/ext/sysvshm/tests/002.phpt @@ -8,7 +8,7 @@ shm_attach() tests $key = ftok(__FILE__, 't'); var_dump(shm_attach()); -var_dump(shm_attach(1,2,3,4)); +var_dump(shm_attach(1,2,3,4,5)); var_dump(shm_attach(-1, 0)); var_dump(shm_attach(0, -1)); @@ -36,7 +36,7 @@ echo "Done\n"; Warning: shm_attach() expects at least 1 parameter, 0 given in %s on line %d NULL -Warning: shm_attach() expects at most 3 parameters, 4 given in %s on line %d +Warning: shm_attach() expects at most 4 parameters, 5 given in %s on line %d NULL Warning: shm_attach(): Segment size must be greater than zero in %s on line %d