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 - shmop - shmop.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 111
Code covered: 65.8 % Executed lines: 73
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP version 4                                                        |
       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                 :    | Authors: Slava Poliakov <hackie@prohost.org>                         |
      16                 :    |          Ilia Alshanetsky <ilia@prohost.org>                         |
      17                 :    +----------------------------------------------------------------------+
      18                 :  */
      19                 : /* $Id: shmop.c 281741 2009-06-06 02:40:14Z mattwil $ */
      20                 : 
      21                 : #ifdef HAVE_CONFIG_H
      22                 : #include "config.h"
      23                 : #endif
      24                 : 
      25                 : #include "php.h"
      26                 : #include "php_ini.h"
      27                 : #include "php_shmop.h"
      28                 : # ifndef PHP_WIN32
      29                 : # include <sys/ipc.h>
      30                 : # include <sys/shm.h>
      31                 : #else
      32                 : #include "tsrm_win32.h"
      33                 : #endif
      34                 : 
      35                 : 
      36                 : #if HAVE_SHMOP
      37                 : 
      38                 : #include "ext/standard/info.h"
      39                 : 
      40                 : #ifdef ZTS
      41                 : int shmop_globals_id;
      42                 : #else
      43                 : php_shmop_globals shmop_globals;
      44                 : #endif
      45                 : 
      46                 : int shm_type;
      47                 : 
      48                 : /* {{{ arginfo */
      49                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_open, 0, 0, 4)
      50                 :         ZEND_ARG_INFO(0, key)
      51                 :         ZEND_ARG_INFO(0, flags)
      52                 :         ZEND_ARG_INFO(0, mode)
      53                 :         ZEND_ARG_INFO(0, size)
      54                 : ZEND_END_ARG_INFO()
      55                 : 
      56                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_read, 0, 0, 3)
      57                 :         ZEND_ARG_INFO(0, shmid)
      58                 :         ZEND_ARG_INFO(0, start)
      59                 :         ZEND_ARG_INFO(0, count)
      60                 : ZEND_END_ARG_INFO()
      61                 : 
      62                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_close, 0, 0, 1)
      63                 :         ZEND_ARG_INFO(0, shmid)
      64                 : ZEND_END_ARG_INFO()
      65                 : 
      66                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_size, 0, 0, 1)
      67                 :         ZEND_ARG_INFO(0, shmid)
      68                 : ZEND_END_ARG_INFO()
      69                 : 
      70                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_write, 0, 0, 3)
      71                 :         ZEND_ARG_INFO(0, shmid)
      72                 :         ZEND_ARG_INFO(0, data)
      73                 :         ZEND_ARG_INFO(0, offset)
      74                 : ZEND_END_ARG_INFO()
      75                 : 
      76                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_delete, 0, 0, 1)
      77                 :         ZEND_ARG_INFO(0, shmid)
      78                 : ZEND_END_ARG_INFO()
      79                 : /* }}} */
      80                 : 
      81                 : /* {{{ shmop_functions[] 
      82                 :  */
      83                 : const zend_function_entry shmop_functions[] = {
      84                 :         PHP_FE(shmop_open,              arginfo_shmop_open)
      85                 :         PHP_FE(shmop_read,              arginfo_shmop_read)
      86                 :         PHP_FE(shmop_close,     arginfo_shmop_close)
      87                 :         PHP_FE(shmop_size,              arginfo_shmop_size)
      88                 :         PHP_FE(shmop_write,     arginfo_shmop_write)
      89                 :         PHP_FE(shmop_delete,    arginfo_shmop_delete)
      90                 :         {NULL, NULL, NULL}      /* Must be the last line in shmop_functions[] */
      91                 : };
      92                 : /* }}} */
      93                 : 
      94                 : /* {{{ shmop_module_entry
      95                 :  */
      96                 : zend_module_entry shmop_module_entry = {
      97                 :         STANDARD_MODULE_HEADER,
      98                 :         "shmop",
      99                 :         shmop_functions,
     100                 :         PHP_MINIT(shmop),
     101                 :         NULL,
     102                 :         NULL,
     103                 :         NULL,
     104                 :         PHP_MINFO(shmop),
     105                 :     NO_VERSION_YET,
     106                 :         STANDARD_MODULE_PROPERTIES
     107                 : };
     108                 : /* }}} */
     109                 : 
     110                 : #ifdef COMPILE_DL_SHMOP
     111                 : ZEND_GET_MODULE(shmop)
     112                 : #endif
     113                 : 
     114                 : #define PHP_SHMOP_GET_RES \
     115                 :         shmop = zend_list_find(shmid, &type);       \
     116                 :         if (!shmop) {   \
     117                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "no shared memory segment with an id of [%lu]", shmid);   \
     118                 :                 RETURN_FALSE;   \
     119                 :         } else if (type != shm_type) {  \
     120                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a shmop resource");  \
     121                 :                 RETURN_FALSE;   \
     122                 :         }       \
     123                 : 
     124                 : /* {{{ rsclean
     125                 :  */
     126                 : static void rsclean(zend_rsrc_list_entry *rsrc TSRMLS_DC)
     127               3 : {
     128               3 :         struct php_shmop *shmop = (struct php_shmop *)rsrc->ptr;
     129                 : 
     130               3 :         shmdt(shmop->addr);
     131               3 :         efree(shmop);
     132               3 : }
     133                 : /* }}} */
     134                 : 
     135                 : /* {{{ PHP_MINIT_FUNCTION
     136                 :  */
     137                 : PHP_MINIT_FUNCTION(shmop)
     138           17007 : {
     139           17007 :         shm_type = zend_register_list_destructors_ex(rsclean, NULL, "shmop", module_number);
     140                 :         
     141           17007 :         return SUCCESS;
     142                 : }
     143                 : /* }}} */
     144                 : 
     145                 : /* {{{ PHP_MINFO_FUNCTION
     146                 :  */
     147                 : PHP_MINFO_FUNCTION(shmop)
     148              43 : {
     149              43 :         php_info_print_table_start();
     150              43 :         php_info_print_table_row(2, "shmop support", "enabled");
     151              43 :         php_info_print_table_end();
     152              43 : }
     153                 : /* }}} */
     154                 : 
     155                 : /* {{{ proto int shmop_open (int key, string flags, int mode, int size) U
     156                 :    gets and attaches a shared memory segment */
     157                 : PHP_FUNCTION(shmop_open)
     158               3 : {
     159                 :         long key, mode, size;
     160                 :         struct php_shmop *shmop;        
     161                 :         struct shmid_ds shm;
     162                 :         int rsid;
     163                 :         char *flags;
     164                 :         int flags_len;
     165                 :         zend_uchar flag_type;
     166                 : 
     167               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ltll", &key, &flags, &flags_len, &flag_type, &mode, &size) == FAILURE) {
     168               0 :                 return;
     169                 :         }
     170                 : 
     171               3 :         if (flag_type == IS_UNICODE) {
     172               3 :                 flags = zend_unicode_to_ascii((UChar*)flags, flags_len TSRMLS_CC);
     173               3 :                 if (!flags) {
     174               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received");
     175               0 :                         RETURN_FALSE;
     176                 :                 }
     177                 :         }
     178                 :         
     179               3 :         if (flags_len != 1) {
     180               0 :                 if (flag_type == IS_UNICODE) {
     181               0 :                         efree(flags);
     182                 :                 }
     183               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a valid flag", flags);
     184               0 :                 RETURN_FALSE;
     185                 :         }
     186                 : 
     187               3 :         shmop = emalloc(sizeof(struct php_shmop));
     188               3 :         memset(shmop, 0, sizeof(struct php_shmop));
     189                 : 
     190               3 :         shmop->key = key;
     191               3 :         shmop->shmflg |= mode;
     192                 : 
     193               3 :         switch (flags[0]) 
     194                 :         {
     195                 :                 case 'a':
     196               1 :                         shmop->shmatflg |= SHM_RDONLY;
     197               1 :                         break;
     198                 :                 case 'c':
     199               0 :                         shmop->shmflg |= IPC_CREAT;
     200               0 :                         shmop->size = size;
     201               0 :                         break;
     202                 :                 case 'n':
     203               1 :                         shmop->shmflg |= (IPC_CREAT | IPC_EXCL);
     204               1 :                         shmop->size = size;
     205               1 :                         break;  
     206                 :                 case 'w':
     207                 :                         /* noop 
     208                 :                                 shm segment is being opened for read & write
     209                 :                                 will fail if segment does not exist
     210                 :                         */
     211               1 :                         break;
     212                 :                 default:
     213               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid access mode");
     214               0 :                         goto err;
     215                 :         }
     216                 : 
     217               3 :         if (shmop->shmflg & IPC_CREAT && shmop->size < 1) {
     218               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Shared memory segment size must be greater than zero");
     219               0 :                 goto err;
     220                 :         }
     221                 : 
     222               3 :         shmop->shmid = shmget(shmop->key, shmop->size, shmop->shmflg);
     223               3 :         if (shmop->shmid == -1) {
     224               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to attach or create shared memory segment");
     225               0 :                 goto err;
     226                 :         }
     227                 : 
     228               3 :         if (shmctl(shmop->shmid, IPC_STAT, &shm)) {
     229               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get shared memory segment information");
     230               0 :                 goto err;
     231                 :         }       
     232                 : 
     233               3 :         shmop->addr = shmat(shmop->shmid, 0, shmop->shmatflg);
     234               3 :         if (shmop->addr == (char*) -1) {
     235               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to attach to shared memory segment");
     236               0 :                 goto err;
     237                 :         }
     238                 : 
     239               3 :         shmop->size = shm.shm_segsz;
     240                 : 
     241               3 :         rsid = zend_list_insert(shmop, shm_type);
     242               3 :         if (flag_type == IS_UNICODE) {
     243               3 :                 efree(flags);
     244                 :         }
     245               3 :         RETURN_LONG(rsid);
     246               0 : err:
     247               0 :         if (flag_type == IS_UNICODE) {
     248               0 :                 efree(flags);
     249                 :         }
     250               0 :         efree(shmop);
     251               0 :         RETURN_FALSE;
     252                 : }
     253                 : /* }}} */
     254                 : 
     255                 : /* {{{ proto string shmop_read (int shmid, int start, int count) U
     256                 :    reads from a shm segment */
     257                 : PHP_FUNCTION(shmop_read)
     258               3 : {
     259                 :         long shmid, start, count;
     260                 :         struct php_shmop *shmop;
     261                 :         int type;
     262                 :         char *startaddr;
     263                 :         int bytes;
     264                 : 
     265               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &shmid, &start, &count) == FAILURE) {
     266               0 :                 return;
     267                 :         }
     268                 : 
     269               3 :         PHP_SHMOP_GET_RES
     270                 : 
     271               3 :         if (start < 0 || start > shmop->size) {
     272               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "start is out of range");
     273               0 :                 RETURN_FALSE;
     274                 :         }
     275                 : 
     276               3 :         if (start + count > shmop->size || count < 0) {
     277               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "count is out of range");
     278               0 :                 RETURN_FALSE;
     279                 :         }
     280                 : 
     281               3 :         startaddr = shmop->addr + start;
     282               3 :         bytes = count ? count : shmop->size - start;
     283                 : 
     284               3 :         RETURN_STRINGL(startaddr, bytes, 1);
     285                 : }
     286                 : /* }}} */
     287                 : 
     288                 : /* {{{ proto void shmop_close (int shmid) U
     289                 :    closes a shared memory segment */
     290                 : PHP_FUNCTION(shmop_close)
     291               3 : {
     292                 :         long shmid;
     293                 :         struct php_shmop *shmop;
     294                 :         int type;
     295                 : 
     296               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &shmid) == FAILURE) {
     297               0 :                 return;
     298                 :         }
     299                 : 
     300               3 :         PHP_SHMOP_GET_RES
     301                 : 
     302               3 :         zend_list_delete(shmid);
     303                 : }
     304                 : /* }}} */
     305                 : 
     306                 : /* {{{ proto int shmop_size (int shmid) U
     307                 :    returns the shm size */
     308                 : PHP_FUNCTION(shmop_size)
     309               1 : {
     310                 :         long shmid;
     311                 :         struct php_shmop *shmop;
     312                 :         int type;
     313                 : 
     314               1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &shmid) == FAILURE) {
     315               0 :                 return;
     316                 :         }
     317                 : 
     318               1 :         PHP_SHMOP_GET_RES
     319                 : 
     320               1 :         RETURN_LONG(shmop->size);
     321                 : }
     322                 : /* }}} */
     323                 : 
     324                 : /* {{{ proto int shmop_write (int shmid, string data, int offset) U
     325                 :    writes to a shared memory segment */
     326                 : PHP_FUNCTION(shmop_write)
     327               3 : {
     328                 :         struct php_shmop *shmop;
     329                 :         int type;
     330                 :         int writesize;
     331               3 :         long shmid, offset=0;
     332                 :         char *data;
     333                 :         int data_len;
     334                 : 
     335               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lS|l", &shmid, &data, &data_len, &offset) == FAILURE) {
     336               0 :                 return;
     337                 :         }
     338                 : 
     339               3 :         PHP_SHMOP_GET_RES
     340                 : 
     341               3 :         if ((shmop->shmatflg & SHM_RDONLY) == SHM_RDONLY) {
     342               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "trying to write to a read only segment");
     343               1 :                 RETURN_FALSE;
     344                 :         }
     345                 : 
     346               2 :         if (offset < 0 || offset > shmop->size) {
     347               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "offset out of range");
     348               0 :                 RETURN_FALSE;
     349                 :         }
     350                 : 
     351               2 :         writesize = (data_len < shmop->size - offset) ? data_len : shmop->size - offset;
     352               2 :         memcpy(shmop->addr + offset, data, writesize);
     353                 : 
     354               2 :         RETURN_LONG(writesize);
     355                 : }
     356                 : /* }}} */
     357                 : 
     358                 : /* {{{ proto bool shmop_delete (int shmid) U
     359                 :    mark segment for deletion */
     360                 : PHP_FUNCTION(shmop_delete)
     361               1 : {
     362                 :         long shmid;
     363                 :         struct php_shmop *shmop;
     364                 :         int type;
     365                 : 
     366               1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &shmid) == FAILURE) {
     367               0 :                 return;
     368                 :         }
     369                 : 
     370               1 :         PHP_SHMOP_GET_RES
     371                 : 
     372               1 :         if (shmctl(shmop->shmid, IPC_RMID, NULL)) {
     373               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "can't mark segment for deletion (are you the owner?)");
     374               0 :                 RETURN_FALSE;
     375                 :         }
     376                 : 
     377               1 :         RETURN_TRUE;
     378                 : }
     379                 : /* }}} */
     380                 : 
     381                 : #endif  /* HAVE_SHMOP */
     382                 : 
     383                 : /*
     384                 :  * Local variables:
     385                 :  * tab-width: 4
     386                 :  * c-basic-offset: 4
     387                 :  * End:
     388                 :  * vim600: sw=4 ts=4 fdm=marker
     389                 :  * vim<600: sw=4 ts=4
     390                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:37 +0000 (33 hours ago)

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