PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - sysvshm - sysvshm.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 133
Code covered: 85.0 % Executed lines: 113
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Author: Christian Cartus <cartus@atrior.de>                          |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 :  
      19                 : /* $Id: sysvshm.c 281742 2009-06-06 02:40:49Z mattwil $ */
      20                 : 
      21                 : /* This has been built and tested on Linux 2.2.14 
      22                 :  *
      23                 :  * This has been built and tested on Solaris 2.6.
      24                 :  * It may not compile or execute correctly on other systems.
      25                 :  */
      26                 : 
      27                 : #ifdef HAVE_CONFIG_H
      28                 : #include "config.h"
      29                 : #endif
      30                 : 
      31                 : #include "php.h"
      32                 : 
      33                 : #if HAVE_SYSVSHM
      34                 : 
      35                 : #include <errno.h>
      36                 : 
      37                 : #include "php_sysvshm.h"
      38                 : #include "ext/standard/php_var.h"
      39                 : #include "ext/standard/php_smart_str.h"
      40                 : #include "php_ini.h"
      41                 : 
      42                 : /* {{{ arginfo */
      43                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_attach, 0, 0, 1)
      44                 :         ZEND_ARG_INFO(0, key)
      45                 :         ZEND_ARG_INFO(0, memsize)
      46                 :         ZEND_ARG_INFO(0, perm)
      47                 : ZEND_END_ARG_INFO()
      48                 : 
      49                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_detach, 0, 0, 1)
      50                 :         ZEND_ARG_INFO(0, shm_identifier)
      51                 : ZEND_END_ARG_INFO()
      52                 : 
      53                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_has_var, 0, 0, 2)
      54                 :         ZEND_ARG_INFO(0, id)
      55                 :         ZEND_ARG_INFO(0, variable_key)
      56                 : ZEND_END_ARG_INFO()
      57                 : 
      58                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_remove, 0, 0, 1)
      59                 :         ZEND_ARG_INFO(0, shm_identifier)
      60                 : ZEND_END_ARG_INFO()
      61                 : 
      62                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_put_var, 0, 0, 3)
      63                 :         ZEND_ARG_INFO(0, shm_identifier)
      64                 :         ZEND_ARG_INFO(0, variable_key)
      65                 :         ZEND_ARG_INFO(0, variable)
      66                 : ZEND_END_ARG_INFO()
      67                 : 
      68                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_get_var, 0, 0, 2)
      69                 :         ZEND_ARG_INFO(0, id)
      70                 :         ZEND_ARG_INFO(0, variable_key)
      71                 : ZEND_END_ARG_INFO()
      72                 : 
      73                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_remove_var, 0, 0, 2)
      74                 :         ZEND_ARG_INFO(0, id)
      75                 :         ZEND_ARG_INFO(0, variable_key)
      76                 : ZEND_END_ARG_INFO()
      77                 : /* }}} */
      78                 : 
      79                 : /* {{{ sysvshm_functions[]
      80                 :  */
      81                 : const zend_function_entry sysvshm_functions[] = {
      82                 :         PHP_FE(shm_attach,              arginfo_shm_attach)
      83                 :         PHP_FE(shm_remove,              arginfo_shm_detach)
      84                 :         PHP_FE(shm_detach,              arginfo_shm_remove)
      85                 :         PHP_FE(shm_put_var,             arginfo_shm_put_var)
      86                 :         PHP_FE(shm_has_var,             arginfo_shm_has_var)
      87                 :         PHP_FE(shm_get_var,             arginfo_shm_get_var)
      88                 :         PHP_FE(shm_remove_var,  arginfo_shm_remove_var)
      89                 :         {NULL, NULL, NULL}      
      90                 : };
      91                 : /* }}} */
      92                 : 
      93                 : /* {{{ sysvshm_module_entry
      94                 :  */
      95                 : zend_module_entry sysvshm_module_entry = {
      96                 :         STANDARD_MODULE_HEADER,
      97                 :         "sysvshm",
      98                 :         sysvshm_functions, 
      99                 :         PHP_MINIT(sysvshm),
     100                 :         NULL,
     101                 :         NULL,
     102                 :         NULL,
     103                 :         NULL,
     104                 :         NO_VERSION_YET,
     105                 :         STANDARD_MODULE_PROPERTIES
     106                 : };
     107                 : /* }}} */
     108                 : 
     109                 : #ifdef COMPILE_DL_SYSVSHM
     110                 : ZEND_GET_MODULE(sysvshm)
     111                 : #endif
     112                 : 
     113                 : #undef shm_ptr                                  /* undefine AIX-specific macro */
     114                 : 
     115                 : #define SHM_FETCH_RESOURCE(shm_ptr, z_ptr) ZEND_FETCH_RESOURCE(shm_ptr, sysvshm_shm *, &z_ptr, -1, PHP_SHM_RSRC_NAME, php_sysvshm.le_shm)
     116                 : 
     117                 : THREAD_LS sysvshm_module php_sysvshm;
     118                 : 
     119                 : static int php_put_shm_data(sysvshm_chunk_head *ptr, long key, const char *data, long len);
     120                 : static long php_check_shm_data(sysvshm_chunk_head *ptr, long key);
     121                 : static int php_remove_shm_data(sysvshm_chunk_head *ptr, long shm_varpos);
     122                 : 
     123                 : /* {{{ php_release_sysvshm
     124                 :  */
     125                 : static void php_release_sysvshm(zend_rsrc_list_entry *rsrc TSRMLS_DC)
     126              12 : {
     127              12 :         sysvshm_shm *shm_ptr = (sysvshm_shm *) rsrc->ptr;
     128              12 :         shmdt((void *) shm_ptr->ptr);
     129              12 :         efree(shm_ptr);
     130              12 : }
     131                 : /* }}} */
     132                 : 
     133                 : /* {{{ PHP_MINIT_FUNCTION
     134                 :  */
     135                 : PHP_MINIT_FUNCTION(sysvshm)
     136           17633 : {
     137           17633 :         php_sysvshm.le_shm = zend_register_list_destructors_ex(php_release_sysvshm, NULL, PHP_SHM_RSRC_NAME, module_number);
     138                 : 
     139           17633 :         if (cfg_get_long("sysvshm.init_mem", &php_sysvshm.init_mem) == FAILURE) {
     140           17633 :                 php_sysvshm.init_mem=10000;
     141                 :         }
     142           17633 :         return SUCCESS;
     143                 : }
     144                 : /* }}} */
     145                 : 
     146                 : /* {{{ proto int shm_attach(int key [, int memsize [, int perm]])
     147                 :    Creates or open a shared memory segment */
     148                 : PHP_FUNCTION(shm_attach)
     149              19 : {
     150                 :         sysvshm_shm *shm_list_ptr;
     151                 :         char *shm_ptr;
     152                 :         sysvshm_chunk_head *chunk_ptr;
     153              19 :         long shm_key, shm_id, shm_size = php_sysvshm.init_mem, shm_flag = 0666;
     154                 : 
     155              19 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &shm_key, &shm_size, &shm_flag)) {
     156               2 :                 return;
     157                 :         }
     158                 : 
     159              17 :         if (shm_size < 1) {
     160               5 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Segment size must be greater than zero");
     161               5 :                 RETURN_FALSE;
     162                 :         }
     163                 : 
     164              12 :         shm_list_ptr = (sysvshm_shm *) emalloc(sizeof(sysvshm_shm));
     165                 : 
     166                 :         /* get the id from a specified key or create new shared memory */
     167              12 :         if ((shm_id = shmget(shm_key, 0, 0)) < 0) {
     168               9 :                 if (shm_size < sizeof(sysvshm_chunk_head)) {
     169               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%lx: memorysize too small", shm_key);
     170               0 :                         efree(shm_list_ptr);
     171               0 :                         RETURN_FALSE;
     172                 :                 }
     173               9 :                 if ((shm_id = shmget(shm_key, shm_size, shm_flag | IPC_CREAT | IPC_EXCL)) < 0) {
     174               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%lx: %s", shm_key, strerror(errno));
     175               0 :                         efree(shm_list_ptr);
     176               0 :                         RETURN_FALSE;
     177                 :                 }
     178                 :         }
     179                 : 
     180              12 :         if ((shm_ptr = shmat(shm_id, NULL, 0)) == (void *) -1) {
     181               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%lx: %s", shm_key, strerror(errno));
     182               0 :                 efree(shm_list_ptr);
     183               0 :                 RETURN_FALSE;
     184                 :         }
     185                 : 
     186                 :         /* check if shm is already initialized */
     187              12 :         chunk_ptr = (sysvshm_chunk_head *) shm_ptr;
     188              12 :         if (strcmp((char*) &(chunk_ptr->magic), "PHP_SM") != 0) {
     189               9 :                 strcpy((char*) &(chunk_ptr->magic), "PHP_SM"); 
     190               9 :                 chunk_ptr->start = sizeof(sysvshm_chunk_head);
     191               9 :                 chunk_ptr->end = chunk_ptr->start;
     192               9 :                 chunk_ptr->total = shm_size;
     193               9 :                 chunk_ptr->free = shm_size-chunk_ptr->end;
     194                 :         }
     195                 : 
     196              12 :         shm_list_ptr->key = shm_key;
     197              12 :         shm_list_ptr->id = shm_id;
     198              12 :         shm_list_ptr->ptr = chunk_ptr;
     199                 :         
     200              12 :         ZEND_REGISTER_RESOURCE(return_value, shm_list_ptr, php_sysvshm.le_shm);
     201                 : }
     202                 : /* }}} */
     203                 : 
     204                 : /* {{{ proto bool shm_detach(resource shm_identifier)
     205                 :    Disconnects from shared memory segment */
     206                 : PHP_FUNCTION(shm_detach)
     207               8 : {
     208                 :         zval *shm_id;
     209                 :         sysvshm_shm *shm_list_ptr;
     210                 : 
     211               8 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &shm_id)) {
     212               5 :                 return;
     213                 :         }
     214               3 :         SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
     215               2 :         RETURN_BOOL(SUCCESS == zend_list_delete(Z_LVAL_P(shm_id)));
     216                 : }
     217                 : /* }}} */
     218                 : 
     219                 : /* {{{ proto bool shm_remove(resource shm_identifier)
     220                 :    Removes shared memory from Unix systems */
     221                 : PHP_FUNCTION(shm_remove)
     222              20 : {
     223                 :         zval *shm_id;
     224                 :         sysvshm_shm *shm_list_ptr;
     225                 : 
     226              20 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &shm_id)) {
     227               7 :                 return;
     228                 :         }
     229              13 :         SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
     230                 :         
     231              11 :         if (shmctl(shm_list_ptr->id, IPC_RMID, NULL) < 0) {
     232               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%x, id %ld: %s", shm_list_ptr->key, Z_LVAL_P(shm_id), strerror(errno));
     233               0 :                 RETURN_FALSE;
     234                 :         }
     235                 : 
     236              11 :         RETURN_TRUE;
     237                 : }
     238                 : /* }}} */
     239                 : 
     240                 : /* {{{ proto bool shm_put_var(resource shm_identifier, int variable_key, mixed variable)
     241                 :    Inserts or updates a variable in shared memory */
     242                 : PHP_FUNCTION(shm_put_var)
     243              18 : {
     244                 :         zval *shm_id, *arg_var;
     245                 :         int ret;
     246                 :         long shm_key;
     247                 :         sysvshm_shm *shm_list_ptr;
     248              18 :         smart_str shm_var = {0};
     249                 :         php_serialize_data_t var_hash;
     250                 : 
     251              18 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &shm_id, &shm_key, &arg_var)) {
     252               3 :                 return;
     253                 :         }
     254              15 :         SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
     255                 :         
     256                 :         /* setup string-variable and serialize */
     257              15 :         PHP_VAR_SERIALIZE_INIT(var_hash);
     258              15 :         php_var_serialize(&shm_var, &arg_var, &var_hash TSRMLS_CC);
     259              15 :         PHP_VAR_SERIALIZE_DESTROY(var_hash);
     260                 :         
     261                 :         /* insert serialized variable into shared memory */
     262              15 :         ret = php_put_shm_data(shm_list_ptr->ptr, shm_key, shm_var.c, shm_var.len);
     263                 : 
     264                 :         /* free string */
     265              15 :         smart_str_free(&shm_var);
     266                 :         
     267              15 :         if (ret == -1) {
     268               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "not enough shared memory left");
     269               1 :                 RETURN_FALSE;
     270                 :         }
     271              14 :         RETURN_TRUE;
     272                 : }
     273                 : /* }}} */
     274                 : 
     275                 : /* {{{ proto mixed shm_get_var(resource id, int variable_key)
     276                 :    Returns a variable from shared memory */
     277                 : PHP_FUNCTION(shm_get_var)
     278              16 : {
     279                 :         zval *shm_id;
     280                 :         long shm_key;
     281                 :         sysvshm_shm *shm_list_ptr;
     282                 :         char *shm_data;
     283                 :         long shm_varpos;
     284                 :         sysvshm_chunk *shm_var;
     285                 :         php_unserialize_data_t var_hash;
     286                 :         
     287              16 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &shm_id, &shm_key)) {
     288               3 :                 return;
     289                 :         }
     290              13 :         SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
     291                 : 
     292                 :         /* setup string-variable and serialize */
     293                 :         /* get serialized variable from shared memory */
     294              13 :         shm_varpos = php_check_shm_data((shm_list_ptr->ptr), shm_key);
     295                 : 
     296              13 :         if (shm_varpos < 0) {
     297               4 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "variable key %ld doesn't exist", shm_key);
     298               4 :                 RETURN_FALSE;
     299                 :         }
     300               9 :         shm_var = (sysvshm_chunk*) ((char *)shm_list_ptr->ptr + shm_varpos);
     301               9 :         shm_data = &shm_var->mem;
     302                 :         
     303               9 :         PHP_VAR_UNSERIALIZE_INIT(var_hash);
     304               9 :         if (php_var_unserialize(&return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash TSRMLS_CC) != 1) {
     305               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "variable data in shared memory is corrupted");
     306               0 :                 RETVAL_FALSE;
     307                 :         }
     308               9 :         PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
     309                 : }
     310                 : /* }}} */
     311                 : 
     312                 : /* {{{ proto bool shm_has_var(resource id, int variable_key)
     313                 :         Checks whether a specific entry exists */
     314                 : PHP_FUNCTION(shm_has_var)
     315               0 : {
     316                 :         zval *shm_id;
     317                 :         long shm_key;
     318                 :         sysvshm_shm *shm_list_ptr;
     319                 :         
     320               0 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &shm_id, &shm_key)) {
     321               0 :                 return;
     322                 :         }
     323               0 :         SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
     324               0 :         RETURN_BOOL(php_check_shm_data(shm_list_ptr->ptr, shm_key) >= 0);
     325                 : }
     326                 : /* }}} */
     327                 : 
     328                 : /* {{{ proto bool shm_remove_var(resource id, int variable_key)
     329                 :    Removes variable from shared memory */
     330                 : PHP_FUNCTION(shm_remove_var)
     331               5 : {
     332                 :         zval *shm_id;
     333                 :         long shm_key, shm_varpos;
     334                 :         sysvshm_shm *shm_list_ptr;
     335                 :         
     336               5 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &shm_id, &shm_key)) {
     337               2 :                 return;
     338                 :         }
     339               3 :         SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
     340                 : 
     341               3 :         shm_varpos = php_check_shm_data((shm_list_ptr->ptr), shm_key);
     342                 : 
     343               3 :         if (shm_varpos < 0) {
     344               2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "variable key %ld doesn't exist", shm_key);
     345               2 :                 RETURN_FALSE;
     346                 :         }
     347               1 :         php_remove_shm_data((shm_list_ptr->ptr), shm_varpos);
     348               1 :         RETURN_TRUE;
     349                 : }
     350                 : /* }}} */
     351                 : 
     352                 : /* {{{ php_put_shm_data
     353                 :  * inserts an ascii-string into shared memory */
     354                 : static int php_put_shm_data(sysvshm_chunk_head *ptr, long key, const char *data, long len)
     355              15 : {
     356                 :         sysvshm_chunk *shm_var;
     357                 :         long total_size;
     358                 :         long shm_varpos;
     359                 : 
     360              15 :         total_size = ((long) (len + sizeof(sysvshm_chunk) - 1) / sizeof(long)) * sizeof(long) + sizeof(long); /* long alligment */
     361                 : 
     362              15 :         if ((shm_varpos = php_check_shm_data(ptr, key)) > 0) {
     363               4 :                 php_remove_shm_data(ptr, shm_varpos);
     364                 :         }
     365                 :         
     366              15 :         if (ptr->free < total_size) {
     367               1 :                 return -1; /* not enough memory */
     368                 :         }
     369                 : 
     370              14 :         shm_var = (sysvshm_chunk *) ((char *) ptr + ptr->end);       
     371              14 :         shm_var->key = key;
     372              14 :         shm_var->length = len;
     373              14 :         shm_var->next = total_size;   
     374              14 :         memcpy(&(shm_var->mem), data, len);      
     375              14 :         ptr->end += total_size;
     376              14 :         ptr->free -= total_size;
     377              14 :         return 0;
     378                 : }
     379                 : /* }}} */
     380                 : 
     381                 : /* {{{ php_check_shm_data
     382                 :  */
     383                 : static long php_check_shm_data(sysvshm_chunk_head *ptr, long key)
     384              31 : {
     385                 :         long pos;
     386                 :         sysvshm_chunk *shm_var;
     387                 : 
     388              31 :         pos = ptr->start;
     389                 :                         
     390                 :         for (;;) {
     391              84 :                 if (pos >= ptr->end) {
     392              17 :                         return -1;
     393                 :                 }
     394              67 :                 shm_var = (sysvshm_chunk*) ((char *) ptr + pos);
     395              67 :                 if (shm_var->key == key) {
     396              14 :                         return pos;
     397                 :                 }       
     398              53 :                 pos += shm_var->next;
     399                 : 
     400              53 :                 if (shm_var->next <= 0 || pos < ptr->start) {
     401               0 :                         return -1;
     402                 :                 }
     403              53 :         }
     404                 :         return -1;
     405                 : }
     406                 : /* }}} */
     407                 : 
     408                 : /* {{{ php_remove_shm_data
     409                 :  */
     410                 : static int php_remove_shm_data(sysvshm_chunk_head *ptr, long shm_varpos)
     411               5 : {
     412                 :         sysvshm_chunk *chunk_ptr, *next_chunk_ptr;
     413                 :         long memcpy_len;
     414                 :         
     415               5 :         chunk_ptr = (sysvshm_chunk *) ((char *) ptr + shm_varpos);
     416               5 :         next_chunk_ptr = (sysvshm_chunk *) ((char *) ptr + shm_varpos + chunk_ptr->next);
     417                 :         
     418               5 :         memcpy_len = ptr->end-shm_varpos - chunk_ptr->next;
     419               5 :         ptr->free += chunk_ptr->next;
     420               5 :         ptr->end -= chunk_ptr->next;
     421               5 :         if (memcpy_len > 0) {
     422               0 :                 memcpy(chunk_ptr, next_chunk_ptr, memcpy_len);
     423                 :         }
     424               5 :         return 0;
     425                 : }
     426                 : /* }}} */
     427                 : 
     428                 : #endif /* HAVE_SYSVSHM */
     429                 : 
     430                 : /*
     431                 :  * Local variables:
     432                 :  * tab-width: 4
     433                 :  * c-basic-offset: 4
     434                 :  * End:
     435                 :  * vim600: sw=4 ts=4 fdm=marker
     436                 :  * vim<600: sw=4 ts=4
     437                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:13 +0000 (3 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.