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-19 Instrumented lines: 171
Code covered: 90.6 % Executed lines: 155
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 277495 2009-03-19 23:10:44Z iliaa $ */
      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                 : /* {{{ sysvshm_functions[]
      43                 :  */
      44                 : zend_function_entry sysvshm_functions[] = {
      45                 :         PHP_FE(shm_attach, NULL)
      46                 :         PHP_FE(shm_remove, NULL)
      47                 :         PHP_FE(shm_detach, NULL)
      48                 :         PHP_FE(shm_put_var, NULL)
      49                 :         PHP_FE(shm_get_var, NULL)
      50                 :         PHP_FE(shm_remove_var, NULL)
      51                 :         {NULL, NULL, NULL}      
      52                 : };
      53                 : /* }}} */
      54                 : 
      55                 : /* {{{ sysvshm_module_entry
      56                 :  */
      57                 : zend_module_entry sysvshm_module_entry = {
      58                 :         STANDARD_MODULE_HEADER,
      59                 :         "sysvshm",
      60                 :         sysvshm_functions, 
      61                 :         PHP_MINIT(sysvshm),
      62                 :         NULL,
      63                 :         NULL,
      64                 :         NULL,
      65                 :         NULL,
      66                 :         NO_VERSION_YET,
      67                 :         STANDARD_MODULE_PROPERTIES
      68                 : };
      69                 : /* }}} */
      70                 : 
      71                 : #ifdef COMPILE_DL_SYSVSHM
      72                 : ZEND_GET_MODULE(sysvshm)
      73                 : #endif
      74                 : 
      75                 : #undef shm_ptr                                  /* undefine AIX-specific macro */
      76                 : 
      77                 : THREAD_LS sysvshm_module php_sysvshm;
      78                 : 
      79                 : static int php_put_shm_data(sysvshm_chunk_head *ptr, long key, char *data, long len);
      80                 : static long php_check_shm_data(sysvshm_chunk_head *ptr, long key);
      81                 : static int php_remove_shm_data(sysvshm_chunk_head *ptr, long shm_varpos);
      82                 : 
      83                 : /* {{{ php_release_sysvshm
      84                 :  */
      85                 : static void php_release_sysvshm(zend_rsrc_list_entry *rsrc TSRMLS_DC)
      86              12 : {
      87              12 :         sysvshm_shm *shm_ptr = (sysvshm_shm *) rsrc->ptr;
      88              12 :         shmdt((void *) shm_ptr->ptr);
      89              12 :         efree(shm_ptr);
      90              12 : }
      91                 : /* }}} */
      92                 : 
      93                 : /* {{{ PHP_MINIT_FUNCTION
      94                 :  */
      95                 : PHP_MINIT_FUNCTION(sysvshm)
      96           13565 : {
      97           13565 :         php_sysvshm.le_shm = zend_register_list_destructors_ex(php_release_sysvshm, NULL, "sysvshm", module_number);
      98                 : 
      99           13565 :         if (cfg_get_long("sysvshm.init_mem", &php_sysvshm.init_mem) == FAILURE) {
     100           13565 :                 php_sysvshm.init_mem=10000;
     101                 :         }
     102           13565 :         return SUCCESS;
     103                 : }
     104                 : /* }}} */
     105                 : 
     106                 : /* {{{ proto int shm_attach(int key [, int memsize [, int perm]])
     107                 :    Creates or open a shared memory segment */
     108                 : PHP_FUNCTION(shm_attach)
     109              19 : {
     110                 :         zval **arg_key, **arg_size, **arg_flag;
     111                 :         long shm_size, shm_flag;
     112                 :         sysvshm_shm *shm_list_ptr;
     113                 :         char *shm_ptr;
     114                 :         sysvshm_chunk_head *chunk_ptr;
     115              19 :         key_t shm_key = (key_t) 0;
     116                 :         long shm_id, list_id;
     117              19 :         int ac = ZEND_NUM_ARGS();
     118                 : 
     119              19 :         shm_flag = 0666;
     120              19 :         shm_size = php_sysvshm.init_mem;
     121                 :         
     122              19 :         if (ac < 1 || ac > 3 || zend_get_parameters_ex(ac, &arg_key, &arg_size, &arg_flag) == FAILURE) {
     123               2 :                 WRONG_PARAM_COUNT;
     124                 :         }
     125                 : 
     126              17 :         switch (ac) {
     127                 :                 case 3:
     128               1 :                         convert_to_long_ex(arg_flag);
     129               1 :                         shm_flag = Z_LVAL_PP(arg_flag);
     130                 :                 case 2:
     131              14 :                         convert_to_long_ex(arg_size);
     132              14 :                         shm_size= Z_LVAL_PP(arg_size);
     133                 :                 case 1:
     134              17 :                         convert_to_long_ex(arg_key);
     135              17 :                         shm_key = Z_LVAL_PP(arg_key);
     136                 :         }
     137                 : 
     138              17 :         if (shm_size < 1) {
     139               5 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Segment size must be greater then zero.");
     140               5 :                 RETURN_FALSE;
     141                 :         }
     142                 : 
     143              12 :         shm_list_ptr = (sysvshm_shm *) emalloc(sizeof(sysvshm_shm));
     144                 : 
     145                 :         /* get the id from a specified key or create new shared memory */
     146              12 :         if ((shm_id = shmget(shm_key, 0, 0)) < 0) {
     147               9 :                 if (shm_size < sizeof(sysvshm_chunk_head)) {
     148               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%x: memorysize too small", shm_key);
     149               0 :                         efree(shm_list_ptr);
     150               0 :                         RETURN_FALSE;
     151                 :                 }
     152               9 :                 if ((shm_id = shmget(shm_key, shm_size, shm_flag | IPC_CREAT | IPC_EXCL)) < 0) {
     153               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%x: %s", shm_key, strerror(errno));
     154               0 :                         efree(shm_list_ptr);
     155               0 :                         RETURN_FALSE;
     156                 :                 }
     157                 :         }
     158                 : 
     159              12 :         if ((shm_ptr = shmat(shm_id, NULL, 0)) == (void *) - 1) {
     160               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%x: %s", shm_key, strerror(errno));
     161               0 :                 efree(shm_list_ptr);
     162               0 :                 RETURN_FALSE;
     163                 :         }
     164                 : 
     165                 :         /* check if shm is already initialized */
     166              12 :         chunk_ptr = (sysvshm_chunk_head *) shm_ptr;
     167              12 :         if (strcmp((char*) &(chunk_ptr->magic), "PHP_SM") != 0) {
     168               9 :                 strcpy((char*) &(chunk_ptr->magic), "PHP_SM"); 
     169               9 :                 chunk_ptr->start = sizeof(sysvshm_chunk_head);
     170               9 :                 chunk_ptr->end = chunk_ptr->start;
     171               9 :                 chunk_ptr->total = shm_size;
     172               9 :                 chunk_ptr->free = shm_size-chunk_ptr->end;
     173                 :         }
     174                 : 
     175              12 :         shm_list_ptr->key = shm_key;
     176              12 :         shm_list_ptr->id = shm_id;
     177              12 :         shm_list_ptr->ptr = chunk_ptr;
     178              12 :         list_id = zend_list_insert(shm_list_ptr, php_sysvshm.le_shm);
     179              12 :         RETURN_LONG(list_id);
     180                 : }
     181                 : /* }}} */
     182                 : 
     183                 : /* {{{ proto bool shm_detach(int shm_identifier)
     184                 :    Disconnects from shared memory segment */
     185                 : PHP_FUNCTION(shm_detach)
     186               8 : {
     187                 :         zval **arg_id;
     188                 :         int type;
     189                 :         sysvshm_shm *shm_list_ptr;
     190                 : 
     191               8 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg_id) == FAILURE) {
     192               2 :                 WRONG_PARAM_COUNT;
     193                 :         }
     194                 : 
     195               6 :         convert_to_long_ex(arg_id);
     196               6 :         shm_list_ptr = (sysvshm_shm *) zend_list_find(Z_LVAL_PP(arg_id), &type);
     197               6 :         if (!shm_list_ptr || type != php_sysvshm.le_shm) {
     198               4 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The parameter is not a valid shm_identifier");
     199               4 :                 RETURN_FALSE;
     200                 :         }
     201                 : 
     202               2 :         zend_list_delete(Z_LVAL_PP(arg_id));
     203                 : 
     204               2 :         RETURN_TRUE;
     205                 : }
     206                 : /* }}} */
     207                 : 
     208                 : /* {{{ proto bool shm_remove(int shm_identifier)
     209                 :    Removes shared memory from Unix systems */
     210                 : PHP_FUNCTION(shm_remove)
     211              20 : {
     212                 :         zval **arg_id;
     213                 :         long id;
     214                 :         int type;
     215                 :         sysvshm_shm *shm_list_ptr;
     216                 : 
     217              20 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg_id) == FAILURE) {
     218               1 :                 WRONG_PARAM_COUNT;
     219                 :         }
     220                 : 
     221              19 :         convert_to_long_ex(arg_id);
     222              19 :         id = Z_LVAL_PP(arg_id);
     223              19 :         shm_list_ptr = (sysvshm_shm *) zend_list_find(id, &type);
     224                 : 
     225              19 :         if (!shm_list_ptr || type != php_sysvshm.le_shm) {
     226               8 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The parameter is not a valid shm_identifier");
     227               8 :                 RETURN_FALSE;
     228                 :         }
     229                 : 
     230              11 :         if (shmctl(shm_list_ptr->id, IPC_RMID,NULL) < 0) {
     231               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%x, id %ld: %s", shm_list_ptr->key, id, strerror(errno));
     232               0 :                 RETURN_FALSE;
     233                 :         } 
     234                 : 
     235              11 :         RETURN_TRUE;
     236                 : }
     237                 : /* }}} */
     238                 : 
     239                 : /* {{{ proto bool shm_put_var(int shm_identifier, int variable_key, mixed variable)
     240                 :    Inserts or updates a variable in shared memory */
     241                 : PHP_FUNCTION(shm_put_var)
     242              18 : {
     243                 :         zval **arg_id, **arg_key, **arg_var;
     244                 :         long key, id;
     245                 :         sysvshm_shm *shm_list_ptr;
     246                 :         int type;
     247              18 :         smart_str shm_var = {0};
     248                 :         int ret;        
     249                 :         php_serialize_data_t var_hash;
     250                 : 
     251              18 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &arg_id, &arg_key, &arg_var) == FAILURE) {
     252               1 :                 WRONG_PARAM_COUNT;
     253                 :         }
     254                 :                         
     255              17 :         convert_to_long_ex(arg_id);
     256              17 :         id = Z_LVAL_PP(arg_id);
     257              17 :         convert_to_long_ex(arg_key);
     258              17 :         key = Z_LVAL_PP(arg_key);
     259                 : 
     260              17 :         shm_list_ptr = (sysvshm_shm *) zend_list_find(id, &type);
     261              17 :         if (!shm_list_ptr || type != php_sysvshm.le_shm) {
     262               2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%ld is not a SysV shared memory index", id);
     263               2 :                 RETURN_FALSE;
     264                 :         }
     265                 : 
     266                 :         /* setup string-variable and serialize */
     267                 : 
     268              15 :         PHP_VAR_SERIALIZE_INIT(var_hash);
     269              15 :         php_var_serialize(&shm_var, arg_var, &var_hash TSRMLS_CC);
     270              15 :         PHP_VAR_SERIALIZE_DESTROY(var_hash);
     271                 :         /* insert serialized variable into shared memory */
     272              15 :         ret = php_put_shm_data(shm_list_ptr->ptr, key, shm_var.c, shm_var.len);
     273                 : 
     274                 :         /* free string */
     275              15 :         smart_str_free(&shm_var);
     276                 :         
     277              15 :         if (ret == -1) {
     278               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "not enough shared memory left");
     279               1 :                 RETURN_FALSE;
     280                 :         }
     281              14 :         RETURN_TRUE;
     282                 : }
     283                 : /* }}} */
     284                 : 
     285                 : /* {{{ proto mixed shm_get_var(int id, int variable_key)
     286                 :    Returns a variable from shared memory */
     287                 : PHP_FUNCTION(shm_get_var)
     288              16 : {
     289                 :         zval **arg_id, **arg_key;
     290                 :         long key, id;
     291                 :         sysvshm_shm *shm_list_ptr;
     292                 :         int type;
     293                 :         char *shm_data; 
     294                 :         long shm_varpos;
     295                 :         sysvshm_chunk *shm_var;
     296                 :         php_unserialize_data_t var_hash;
     297                 :         
     298              16 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg_id, &arg_key) == FAILURE) {
     299               1 :                 WRONG_PARAM_COUNT;
     300                 :         }
     301                 : 
     302              15 :         convert_to_long_ex(arg_id);
     303              15 :         id = Z_LVAL_PP(arg_id);
     304              15 :         convert_to_long_ex(arg_key);
     305              15 :         key = Z_LVAL_PP(arg_key);
     306                 : 
     307              15 :         shm_list_ptr = (sysvshm_shm *) zend_list_find(id, &type);
     308              15 :         if (!shm_list_ptr || type != php_sysvshm.le_shm) {
     309               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%ld is not a SysV shared memory index", id);
     310               1 :                 RETURN_FALSE;
     311                 :         }
     312                 : 
     313                 :         /* setup string-variable and serialize */
     314                 :         /* get serialized variable from shared memory */
     315              14 :         shm_varpos = php_check_shm_data((shm_list_ptr->ptr), key);
     316                 : 
     317              14 :         if (shm_varpos < 0) {
     318               4 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "variable key %ld doesn't exist", key);
     319               4 :                 RETURN_FALSE;
     320                 :         }
     321              10 :         shm_var = (sysvshm_chunk*) ((char *)shm_list_ptr->ptr + shm_varpos);
     322              10 :         shm_data = &shm_var->mem;
     323                 :         
     324              10 :         PHP_VAR_UNSERIALIZE_INIT(var_hash);
     325              10 :         if (php_var_unserialize(&return_value, (const unsigned char **) &shm_data, shm_data + shm_var->length, &var_hash TSRMLS_CC) != 1) {
     326               0 :                 PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
     327               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "variable data in shared memory is corrupted");
     328               0 :                 RETURN_FALSE;
     329                 :         }
     330              10 :         PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
     331                 : }
     332                 : /* }}} */
     333                 : 
     334                 : /* {{{ proto bool shm_remove_var(int id, int variable_key)
     335                 :    Removes variable from shared memory */
     336                 : PHP_FUNCTION(shm_remove_var)
     337               5 : {
     338                 :         zval **arg_id, **arg_key;
     339                 :         long key, id;
     340                 :         sysvshm_shm *shm_list_ptr;
     341                 :         int type;
     342                 :         long shm_varpos;
     343                 :         
     344               5 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg_id, &arg_key) == FAILURE) {
     345               1 :                 WRONG_PARAM_COUNT;
     346                 :         }
     347                 : 
     348               4 :         convert_to_long_ex(arg_id);
     349               4 :         id = Z_LVAL_PP(arg_id);
     350               4 :         convert_to_long_ex(arg_key);
     351               4 :         key = Z_LVAL_PP(arg_key);
     352                 : 
     353               4 :         shm_list_ptr = (sysvshm_shm *) zend_list_find(id, &type);
     354               4 :         if (!shm_list_ptr || type != php_sysvshm.le_shm) {
     355               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%ld is not a SysV shared memory index", id);
     356               1 :                 RETURN_FALSE;
     357                 :         }
     358                 : 
     359               3 :         shm_varpos = php_check_shm_data((shm_list_ptr->ptr), key);
     360                 : 
     361               3 :         if (shm_varpos < 0) {
     362               2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "variable key %ld doesn't exist", key);
     363               2 :                 RETURN_FALSE;
     364                 :         }
     365               1 :         php_remove_shm_data((shm_list_ptr->ptr), shm_varpos);        
     366               1 :         RETURN_TRUE;
     367                 : }
     368                 : /* }}} */
     369                 : 
     370                 : /* {{{ php_put_shm_data
     371                 :  * inserts an ascii-string into shared memory */
     372                 : static int php_put_shm_data(sysvshm_chunk_head *ptr, long key, char *data, long len)
     373              15 : {
     374                 :         sysvshm_chunk *shm_var;
     375                 :         long total_size;
     376                 :         long shm_varpos;
     377                 : 
     378              15 :         total_size = ((long) (len + sizeof(sysvshm_chunk) - 1) / sizeof(long)) * sizeof(long) + sizeof(long); /* long alligment */
     379                 : 
     380              15 :         if ((shm_varpos = php_check_shm_data(ptr, key)) > 0) {
     381               4 :                 php_remove_shm_data(ptr, shm_varpos);
     382                 :         }
     383                 :         
     384              15 :         if (ptr->free < total_size) {
     385               1 :                 return -1; /* not enough memeory */
     386                 :         }
     387                 : 
     388              14 :         shm_var = (sysvshm_chunk *) ((char *) ptr + ptr->end);       
     389              14 :         shm_var->key = key;
     390              14 :         shm_var->length = len;
     391              14 :         shm_var->next = total_size;   
     392              14 :         memcpy(&(shm_var->mem), data, len);      
     393              14 :         ptr->end += total_size;
     394              14 :         ptr->free -= total_size;
     395              14 :         return 0;
     396                 : }
     397                 : /* }}} */
     398                 : 
     399                 : /* {{{ php_check_shm_data
     400                 :  */
     401                 : static long php_check_shm_data(sysvshm_chunk_head *ptr, long key)
     402              32 : {
     403                 :         long pos;
     404                 :         sysvshm_chunk *shm_var;
     405                 : 
     406              32 :         pos = ptr->start;
     407                 :                         
     408                 :         for (;;) {
     409              86 :                 if (pos >= ptr->end) {
     410              17 :                         return -1;
     411                 :                 }
     412              69 :                 shm_var = (sysvshm_chunk*) ((char *) ptr + pos);
     413              69 :                 if (shm_var->key == key) {
     414              15 :                         return pos;
     415                 :                 }       
     416              54 :                 pos += shm_var->next;
     417                 : 
     418              54 :                 if (shm_var->next <= 0 || pos < ptr->start) {
     419               0 :                         return -1;
     420                 :                 }
     421              54 :         }
     422                 :         return -1;
     423                 : }
     424                 : /* }}} */
     425                 : 
     426                 : /* {{{ php_remove_shm_data
     427                 :  */
     428                 : static int php_remove_shm_data(sysvshm_chunk_head *ptr, long shm_varpos)
     429               5 : {
     430                 :         sysvshm_chunk *chunk_ptr, *next_chunk_ptr;
     431                 :         long memcpy_len;
     432                 :         
     433               5 :         chunk_ptr = (sysvshm_chunk *) ((char *) ptr + shm_varpos);
     434               5 :         next_chunk_ptr = (sysvshm_chunk *) ((char *) ptr + shm_varpos + chunk_ptr->next);
     435                 :         
     436               5 :         memcpy_len = ptr->end-shm_varpos - chunk_ptr->next;
     437               5 :         ptr->free += chunk_ptr->next;
     438               5 :         ptr->end -= chunk_ptr->next;
     439               5 :         if (memcpy_len > 0) {
     440               0 :                 memcpy(chunk_ptr, next_chunk_ptr, memcpy_len);
     441                 :         }
     442               5 :         return 0;
     443                 : }
     444                 : /* }}} */
     445                 : 
     446                 : #endif /* HAVE_SYSVSHM */
     447                 : 
     448                 : /*
     449                 :  * Local variables:
     450                 :  * tab-width: 4
     451                 :  * c-basic-offset: 4
     452                 :  * End:
     453                 :  * vim600: sw=4 ts=4 fdm=marker
     454                 :  * vim<600: sw=4 ts=4
     455                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:24 +0000 (5 days ago)

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