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

LCOV - code coverage report
Current view: top level - ext/shmop - shmop.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 70 101 69.3 %
Date: 2014-04-18 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2013 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$ */
      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             :         PHP_FE_END
      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           3 : static void rsclean(zend_rsrc_list_entry *rsrc TSRMLS_DC)
     127             : {
     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       19341 : PHP_MINIT_FUNCTION(shmop)
     138             : {
     139       19341 :         shm_type = zend_register_list_destructors_ex(rsclean, NULL, "shmop", module_number);
     140             :         
     141       19341 :         return SUCCESS;
     142             : }
     143             : /* }}} */
     144             : 
     145             : /* {{{ PHP_MINFO_FUNCTION
     146             :  */
     147         148 : PHP_MINFO_FUNCTION(shmop)
     148             : {
     149         148 :         php_info_print_table_start();
     150         148 :         php_info_print_table_row(2, "shmop support", "enabled");
     151         148 :         php_info_print_table_end();
     152         148 : }
     153             : /* }}} */
     154             : 
     155             : /* {{{ proto int shmop_open (int key, string flags, int mode, int size)
     156             :    gets and attaches a shared memory segment */
     157           3 : PHP_FUNCTION(shmop_open)
     158             : {
     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             : 
     166           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsll", &key, &flags, &flags_len, &mode, &size) == FAILURE) {
     167           0 :                 return;
     168             :         }
     169             : 
     170           3 :         if (flags_len != 1) {
     171           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a valid flag", flags);
     172           0 :                 RETURN_FALSE;
     173             :         }
     174             : 
     175           3 :         shmop = emalloc(sizeof(struct php_shmop));
     176           3 :         memset(shmop, 0, sizeof(struct php_shmop));
     177             : 
     178           3 :         shmop->key = key;
     179           3 :         shmop->shmflg |= mode;
     180             : 
     181           3 :         switch (flags[0]) 
     182             :         {
     183             :                 case 'a':
     184           1 :                         shmop->shmatflg |= SHM_RDONLY;
     185           1 :                         break;
     186             :                 case 'c':
     187           0 :                         shmop->shmflg |= IPC_CREAT;
     188           0 :                         shmop->size = size;
     189           0 :                         break;
     190             :                 case 'n':
     191           1 :                         shmop->shmflg |= (IPC_CREAT | IPC_EXCL);
     192           1 :                         shmop->size = size;
     193           1 :                         break;  
     194             :                 case 'w':
     195             :                         /* noop 
     196             :                                 shm segment is being opened for read & write
     197             :                                 will fail if segment does not exist
     198             :                         */
     199           1 :                         break;
     200             :                 default:
     201           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid access mode");
     202           0 :                         goto err;
     203             :         }
     204             : 
     205           3 :         if (shmop->shmflg & IPC_CREAT && shmop->size < 1) {
     206           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Shared memory segment size must be greater than zero");
     207           0 :                 goto err;
     208             :         }
     209             : 
     210           3 :         shmop->shmid = shmget(shmop->key, shmop->size, shmop->shmflg);
     211           3 :         if (shmop->shmid == -1) {
     212           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to attach or create shared memory segment");
     213           0 :                 goto err;
     214             :         }
     215             : 
     216           3 :         if (shmctl(shmop->shmid, IPC_STAT, &shm)) {
     217           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get shared memory segment information");
     218           0 :                 goto err;
     219             :         }       
     220             : 
     221           3 :         shmop->addr = shmat(shmop->shmid, 0, shmop->shmatflg);
     222           3 :         if (shmop->addr == (char*) -1) {
     223           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to attach to shared memory segment");
     224           0 :                 goto err;
     225             :         }
     226             : 
     227           3 :         shmop->size = shm.shm_segsz;
     228             : 
     229           3 :         rsid = zend_list_insert(shmop, shm_type);
     230           3 :         RETURN_LONG(rsid);
     231             : err:
     232           0 :         efree(shmop);
     233           0 :         RETURN_FALSE;
     234             : }
     235             : /* }}} */
     236             : 
     237             : /* {{{ proto string shmop_read (int shmid, int start, int count)
     238             :    reads from a shm segment */
     239           3 : PHP_FUNCTION(shmop_read)
     240             : {
     241             :         long shmid, start, count;
     242             :         struct php_shmop *shmop;
     243             :         int type;
     244             :         char *startaddr;
     245             :         int bytes;
     246             :         char *return_string;
     247             : 
     248           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &shmid, &start, &count) == FAILURE) {
     249           0 :                 return;
     250             :         }
     251             : 
     252           3 :         PHP_SHMOP_GET_RES
     253             : 
     254           3 :         if (start < 0 || start > shmop->size) {
     255           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "start is out of range");
     256           0 :                 RETURN_FALSE;
     257             :         }
     258             : 
     259           3 :         if (count < 0 || start > (INT_MAX - count) || start + count > shmop->size) {
     260           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "count is out of range");
     261           0 :                 RETURN_FALSE;
     262             :         }
     263             : 
     264           3 :         startaddr = shmop->addr + start;
     265           3 :         bytes = count ? count : shmop->size - start;
     266             : 
     267           3 :         return_string = emalloc(bytes+1);
     268           3 :         memcpy(return_string, startaddr, bytes);
     269           3 :         return_string[bytes] = 0;
     270             : 
     271           3 :         RETURN_STRINGL(return_string, bytes, 0);
     272             : }
     273             : /* }}} */
     274             : 
     275             : /* {{{ proto void shmop_close (int shmid)
     276             :    closes a shared memory segment */
     277           3 : PHP_FUNCTION(shmop_close)
     278             : {
     279             :         long shmid;
     280             :         struct php_shmop *shmop;
     281             :         int type;
     282             : 
     283           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &shmid) == FAILURE) {
     284           0 :                 return;
     285             :         }
     286             : 
     287           3 :         PHP_SHMOP_GET_RES
     288             : 
     289           3 :         zend_list_delete(shmid);
     290             : }
     291             : /* }}} */
     292             : 
     293             : /* {{{ proto int shmop_size (int shmid)
     294             :    returns the shm size */
     295           1 : PHP_FUNCTION(shmop_size)
     296             : {
     297             :         long shmid;
     298             :         struct php_shmop *shmop;
     299             :         int type;
     300             : 
     301           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &shmid) == FAILURE) {
     302           0 :                 return;
     303             :         }
     304             : 
     305           1 :         PHP_SHMOP_GET_RES
     306             : 
     307           1 :         RETURN_LONG(shmop->size);
     308             : }
     309             : /* }}} */
     310             : 
     311             : /* {{{ proto int shmop_write (int shmid, string data, int offset)
     312             :    writes to a shared memory segment */
     313           3 : PHP_FUNCTION(shmop_write)
     314             : {
     315             :         struct php_shmop *shmop;
     316             :         int type;
     317             :         int writesize;
     318             :         long shmid, offset;
     319             :         char *data;
     320             :         int data_len;
     321             : 
     322           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsl", &shmid, &data, &data_len, &offset) == FAILURE) {
     323           0 :                 return;
     324             :         }
     325             : 
     326           3 :         PHP_SHMOP_GET_RES
     327             : 
     328           3 :         if ((shmop->shmatflg & SHM_RDONLY) == SHM_RDONLY) {
     329           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "trying to write to a read only segment");
     330           1 :                 RETURN_FALSE;
     331             :         }
     332             : 
     333           2 :         if (offset < 0 || offset > shmop->size) {
     334           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "offset out of range");
     335           0 :                 RETURN_FALSE;
     336             :         }
     337             : 
     338           2 :         writesize = (data_len < shmop->size - offset) ? data_len : shmop->size - offset;
     339           2 :         memcpy(shmop->addr + offset, data, writesize);
     340             : 
     341           2 :         RETURN_LONG(writesize);
     342             : }
     343             : /* }}} */
     344             : 
     345             : /* {{{ proto bool shmop_delete (int shmid)
     346             :    mark segment for deletion */
     347           1 : PHP_FUNCTION(shmop_delete)
     348             : {
     349             :         long shmid;
     350             :         struct php_shmop *shmop;
     351             :         int type;
     352             : 
     353           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &shmid) == FAILURE) {
     354           0 :                 return;
     355             :         }
     356             : 
     357           1 :         PHP_SHMOP_GET_RES
     358             : 
     359           1 :         if (shmctl(shmop->shmid, IPC_RMID, NULL)) {
     360           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "can't mark segment for deletion (are you the owner?)");
     361           0 :                 RETURN_FALSE;
     362             :         }
     363             : 
     364           1 :         RETURN_TRUE;
     365             : }
     366             : /* }}} */
     367             : 
     368             : #endif  /* HAVE_SHMOP */
     369             : 
     370             : /*
     371             :  * Local variables:
     372             :  * tab-width: 4
     373             :  * c-basic-offset: 4
     374             :  * End:
     375             :  * vim600: sw=4 ts=4 fdm=marker
     376             :  * vim<600: sw=4 ts=4
     377             :  */

Generated by: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:33 +0000 (5 days ago)

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