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 - pcntl - pcntl.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 415
Code covered: 87.0 % Executed lines: 361
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 6                                                        |
       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: Jason Greene <jason@inetgurus.net>                           |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: pcntl.c 288993 2009-09-30 13:04:28Z dmitry $ */
      20                 : 
      21                 : #define PCNTL_DEBUG 0
      22                 : 
      23                 : #if PCNTL_DEBUG
      24                 : #define DEBUG_OUT printf("DEBUG: ");printf
      25                 : #define IF_DEBUG(z) z
      26                 : #else
      27                 : #define IF_DEBUG(z)
      28                 : #endif
      29                 : 
      30                 : #ifdef HAVE_CONFIG_H
      31                 : #include "config.h"
      32                 : #endif
      33                 : 
      34                 : #include "php.h"
      35                 : #include "php_ini.h"
      36                 : #include "ext/standard/info.h"
      37                 : #include "php_pcntl.h"
      38                 : #include "php_signal.h"
      39                 : #include "php_ticks.h"
      40                 : 
      41                 : #if HAVE_GETPRIORITY || HAVE_SETPRIORITY || HAVE_WAIT3
      42                 : #include <sys/wait.h>
      43                 : #include <sys/time.h>
      44                 : #include <sys/resource.h>
      45                 : #endif
      46                 : 
      47                 : ZEND_DECLARE_MODULE_GLOBALS(pcntl)
      48                 : static PHP_GINIT_FUNCTION(pcntl);
      49                 : 
      50                 : /* {{{ arginfo */
      51                 : ZEND_BEGIN_ARG_INFO(arginfo_pcntl_void, 0)
      52                 : ZEND_END_ARG_INFO()
      53                 : 
      54                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_waitpid, 0, 0, 2)
      55                 :         ZEND_ARG_INFO(0, pid)
      56                 :         ZEND_ARG_INFO(1, status)
      57                 :         ZEND_ARG_INFO(0, options)
      58                 : ZEND_END_ARG_INFO()
      59                 : 
      60                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wait, 0, 0, 1)
      61                 :         ZEND_ARG_INFO(1, status)
      62                 :         ZEND_ARG_INFO(0, options)
      63                 : ZEND_END_ARG_INFO()
      64                 : 
      65                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_signal, 0, 0, 2)
      66                 :         ZEND_ARG_INFO(0, signo)
      67                 :         ZEND_ARG_INFO(0, handler)
      68                 :         ZEND_ARG_INFO(0, restart_syscalls)
      69                 : ZEND_END_ARG_INFO()
      70                 : 
      71                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_sigprocmask, 0, 0, 2)
      72                 :         ZEND_ARG_INFO(0, how)
      73                 :         ZEND_ARG_INFO(0, set)
      74                 :         ZEND_ARG_INFO(1, oldset)
      75                 : ZEND_END_ARG_INFO()
      76                 : 
      77                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_sigwaitinfo, 0, 0, 1)
      78                 :         ZEND_ARG_INFO(0, set)
      79                 :         ZEND_ARG_INFO(1, info)
      80                 : ZEND_END_ARG_INFO()
      81                 : 
      82                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_sigtimedwait, 0, 0, 1)
      83                 :         ZEND_ARG_INFO(0, set)
      84                 :         ZEND_ARG_INFO(1, info)
      85                 :         ZEND_ARG_INFO(0, seconds)
      86                 :         ZEND_ARG_INFO(0, nanoseconds)
      87                 : ZEND_END_ARG_INFO()
      88                 : 
      89                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifexited, 0, 0, 1)
      90                 :         ZEND_ARG_INFO(0, status)
      91                 : ZEND_END_ARG_INFO()
      92                 : 
      93                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifstopped, 0, 0, 1)
      94                 :         ZEND_ARG_INFO(0, status)
      95                 : ZEND_END_ARG_INFO()
      96                 : 
      97                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifsignaled, 0, 0, 1)
      98                 :         ZEND_ARG_INFO(0, status)
      99                 : ZEND_END_ARG_INFO()
     100                 : 
     101                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifexitstatus, 0, 0, 1)
     102                 :         ZEND_ARG_INFO(0, status)
     103                 : ZEND_END_ARG_INFO()
     104                 : 
     105                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wtermsig, 0, 0, 1)
     106                 :         ZEND_ARG_INFO(0, status)
     107                 : ZEND_END_ARG_INFO()
     108                 : 
     109                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wstopsig, 0, 0, 1)
     110                 :         ZEND_ARG_INFO(0, status)
     111                 : ZEND_END_ARG_INFO()
     112                 : 
     113                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_exec, 0, 0, 1)
     114                 :         ZEND_ARG_INFO(0, path)
     115                 :         ZEND_ARG_INFO(0, args)
     116                 :         ZEND_ARG_INFO(0, envs)
     117                 : ZEND_END_ARG_INFO()
     118                 : 
     119                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_alarm, 0, 0, 1)
     120                 :         ZEND_ARG_INFO(0, seconds)
     121                 : ZEND_END_ARG_INFO()
     122                 : 
     123                 : #ifdef HAVE_GETPRIORITY
     124                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_getpriority, 0, 0, 0)
     125                 :         ZEND_ARG_INFO(0, pid)
     126                 :         ZEND_ARG_INFO(0, process_identifier)
     127                 : ZEND_END_ARG_INFO()
     128                 : #endif
     129                 : 
     130                 : #ifdef HAVE_SETPRIORITY
     131                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_setpriority, 0, 0, 1)
     132                 :         ZEND_ARG_INFO(0, priority)
     133                 :         ZEND_ARG_INFO(0, pid)
     134                 :         ZEND_ARG_INFO(0, process_identifier)
     135                 : ZEND_END_ARG_INFO()
     136                 : #endif
     137                 : /* }}} */
     138                 : 
     139                 : const zend_function_entry pcntl_functions[] = {
     140                 :         PHP_FE(pcntl_fork,                      arginfo_pcntl_void)
     141                 :         PHP_FE(pcntl_waitpid,           arginfo_pcntl_waitpid)
     142                 :         PHP_FE(pcntl_wait,                      arginfo_pcntl_wait)
     143                 :         PHP_FE(pcntl_signal,            arginfo_pcntl_signal)
     144                 :         PHP_FE(pcntl_signal_dispatch,   arginfo_pcntl_void)
     145                 :         PHP_FE(pcntl_wifexited,         arginfo_pcntl_wifexited)
     146                 :         PHP_FE(pcntl_wifstopped,        arginfo_pcntl_wifstopped)
     147                 :         PHP_FE(pcntl_wifsignaled,       arginfo_pcntl_wifsignaled)
     148                 :         PHP_FE(pcntl_wexitstatus,       arginfo_pcntl_wifexitstatus)
     149                 :         PHP_FE(pcntl_wtermsig,          arginfo_pcntl_wtermsig)
     150                 :         PHP_FE(pcntl_wstopsig,          arginfo_pcntl_wstopsig)
     151                 :         PHP_FE(pcntl_exec,                      arginfo_pcntl_exec)
     152                 :         PHP_FE(pcntl_alarm,                     arginfo_pcntl_alarm)
     153                 : #ifdef HAVE_GETPRIORITY
     154                 :         PHP_FE(pcntl_getpriority,       arginfo_pcntl_getpriority)
     155                 : #endif
     156                 : #ifdef HAVE_SETPRIORITY
     157                 :         PHP_FE(pcntl_setpriority,       arginfo_pcntl_setpriority)
     158                 : #endif
     159                 : #ifdef HAVE_SIGPROCMASK
     160                 :         PHP_FE(pcntl_sigprocmask,       arginfo_pcntl_sigprocmask)
     161                 : #endif
     162                 : #if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
     163                 :         PHP_FE(pcntl_sigwaitinfo,       arginfo_pcntl_sigwaitinfo)
     164                 :         PHP_FE(pcntl_sigtimedwait,      arginfo_pcntl_sigtimedwait)
     165                 : #endif
     166                 :         {NULL, NULL, NULL}      
     167                 : };
     168                 : 
     169                 : zend_module_entry pcntl_module_entry = {
     170                 :         STANDARD_MODULE_HEADER,
     171                 :         "pcntl",
     172                 :         pcntl_functions,
     173                 :         PHP_MINIT(pcntl),
     174                 :         PHP_MSHUTDOWN(pcntl),
     175                 :         PHP_RINIT(pcntl),
     176                 :         PHP_RSHUTDOWN(pcntl),
     177                 :         PHP_MINFO(pcntl),
     178                 :         NO_VERSION_YET,
     179                 :         PHP_MODULE_GLOBALS(pcntl),
     180                 :         PHP_GINIT(pcntl),
     181                 :         NULL,
     182                 :         NULL,
     183                 :         STANDARD_MODULE_PROPERTIES_EX
     184                 : };
     185                 : 
     186                 : #ifdef COMPILE_DL_PCNTL
     187                 : ZEND_GET_MODULE(pcntl)
     188                 : #endif
     189                 : 
     190                 : static void pcntl_signal_handler(int);
     191                 : static void pcntl_signal_dispatch();
     192                 :   
     193                 : void php_register_signal_constants(INIT_FUNC_ARGS)
     194           17007 : {
     195                 : 
     196                 :         /* Wait Constants */
     197                 : #ifdef WNOHANG
     198           17007 :         REGISTER_LONG_CONSTANT("WNOHANG",  (long) WNOHANG, CONST_CS | CONST_PERSISTENT);
     199                 : #endif
     200                 : #ifdef WUNTRACED
     201           17007 :         REGISTER_LONG_CONSTANT("WUNTRACED",  (long) WUNTRACED, CONST_CS | CONST_PERSISTENT);
     202                 : #endif
     203                 : 
     204                 :         /* Signal Constants */
     205           17007 :         REGISTER_LONG_CONSTANT("SIG_IGN",  (long) SIG_IGN, CONST_CS | CONST_PERSISTENT);
     206           17007 :         REGISTER_LONG_CONSTANT("SIG_DFL",  (long) SIG_DFL, CONST_CS | CONST_PERSISTENT);
     207           17007 :         REGISTER_LONG_CONSTANT("SIG_ERR",  (long) SIG_ERR, CONST_CS | CONST_PERSISTENT);
     208           17007 :         REGISTER_LONG_CONSTANT("SIGHUP",   (long) SIGHUP,  CONST_CS | CONST_PERSISTENT);
     209           17007 :         REGISTER_LONG_CONSTANT("SIGINT",   (long) SIGINT,  CONST_CS | CONST_PERSISTENT);
     210           17007 :         REGISTER_LONG_CONSTANT("SIGQUIT",  (long) SIGQUIT, CONST_CS | CONST_PERSISTENT);
     211           17007 :         REGISTER_LONG_CONSTANT("SIGILL",   (long) SIGILL,  CONST_CS | CONST_PERSISTENT);
     212           17007 :         REGISTER_LONG_CONSTANT("SIGTRAP",  (long) SIGTRAP, CONST_CS | CONST_PERSISTENT);
     213           17007 :         REGISTER_LONG_CONSTANT("SIGABRT",  (long) SIGABRT, CONST_CS | CONST_PERSISTENT);
     214                 : #ifdef SIGIOT
     215           17007 :         REGISTER_LONG_CONSTANT("SIGIOT",   (long) SIGIOT,  CONST_CS | CONST_PERSISTENT);
     216                 : #endif
     217           17007 :         REGISTER_LONG_CONSTANT("SIGBUS",   (long) SIGBUS,  CONST_CS | CONST_PERSISTENT);
     218           17007 :         REGISTER_LONG_CONSTANT("SIGFPE",   (long) SIGFPE,  CONST_CS | CONST_PERSISTENT);
     219           17007 :         REGISTER_LONG_CONSTANT("SIGKILL",  (long) SIGKILL, CONST_CS | CONST_PERSISTENT);
     220           17007 :         REGISTER_LONG_CONSTANT("SIGUSR1",  (long) SIGUSR1, CONST_CS | CONST_PERSISTENT);
     221           17007 :         REGISTER_LONG_CONSTANT("SIGSEGV",  (long) SIGSEGV, CONST_CS | CONST_PERSISTENT);
     222           17007 :         REGISTER_LONG_CONSTANT("SIGUSR2",  (long) SIGUSR2, CONST_CS | CONST_PERSISTENT);
     223           17007 :         REGISTER_LONG_CONSTANT("SIGPIPE",  (long) SIGPIPE, CONST_CS | CONST_PERSISTENT);
     224           17007 :         REGISTER_LONG_CONSTANT("SIGALRM",  (long) SIGALRM, CONST_CS | CONST_PERSISTENT);
     225           17007 :         REGISTER_LONG_CONSTANT("SIGTERM",  (long) SIGTERM, CONST_CS | CONST_PERSISTENT);
     226                 : #ifdef SIGSTKFLT
     227           17007 :         REGISTER_LONG_CONSTANT("SIGSTKFLT",(long) SIGSTKFLT, CONST_CS | CONST_PERSISTENT);
     228                 : #endif 
     229                 : #ifdef SIGCLD
     230           17007 :         REGISTER_LONG_CONSTANT("SIGCLD",   (long) SIGCLD, CONST_CS | CONST_PERSISTENT);
     231                 : #endif
     232                 : #ifdef SIGCHLD
     233           17007 :         REGISTER_LONG_CONSTANT("SIGCHLD",  (long) SIGCHLD, CONST_CS | CONST_PERSISTENT);
     234                 : #endif
     235           17007 :         REGISTER_LONG_CONSTANT("SIGCONT",  (long) SIGCONT, CONST_CS | CONST_PERSISTENT);
     236           17007 :         REGISTER_LONG_CONSTANT("SIGSTOP",  (long) SIGSTOP, CONST_CS | CONST_PERSISTENT);
     237           17007 :         REGISTER_LONG_CONSTANT("SIGTSTP",  (long) SIGTSTP, CONST_CS | CONST_PERSISTENT);
     238           17007 :         REGISTER_LONG_CONSTANT("SIGTTIN",  (long) SIGTTIN, CONST_CS | CONST_PERSISTENT);
     239           17007 :         REGISTER_LONG_CONSTANT("SIGTTOU",  (long) SIGTTOU, CONST_CS | CONST_PERSISTENT);
     240           17007 :         REGISTER_LONG_CONSTANT("SIGURG",   (long) SIGURG , CONST_CS | CONST_PERSISTENT);
     241           17007 :         REGISTER_LONG_CONSTANT("SIGXCPU",  (long) SIGXCPU, CONST_CS | CONST_PERSISTENT);
     242           17007 :         REGISTER_LONG_CONSTANT("SIGXFSZ",  (long) SIGXFSZ, CONST_CS | CONST_PERSISTENT);
     243           17007 :         REGISTER_LONG_CONSTANT("SIGVTALRM",(long) SIGVTALRM, CONST_CS | CONST_PERSISTENT);
     244           17007 :         REGISTER_LONG_CONSTANT("SIGPROF",  (long) SIGPROF, CONST_CS | CONST_PERSISTENT);
     245           17007 :         REGISTER_LONG_CONSTANT("SIGWINCH", (long) SIGWINCH, CONST_CS | CONST_PERSISTENT);
     246                 : #ifdef SIGPOLL
     247           17007 :         REGISTER_LONG_CONSTANT("SIGPOLL",  (long) SIGPOLL, CONST_CS | CONST_PERSISTENT);
     248                 : #endif
     249           17007 :         REGISTER_LONG_CONSTANT("SIGIO",    (long) SIGIO, CONST_CS | CONST_PERSISTENT);
     250                 : #ifdef SIGPWR
     251           17007 :         REGISTER_LONG_CONSTANT("SIGPWR",   (long) SIGPWR, CONST_CS | CONST_PERSISTENT);
     252                 : #endif
     253                 : #ifdef SIGSYS
     254           17007 :         REGISTER_LONG_CONSTANT("SIGSYS",   (long) SIGSYS, CONST_CS | CONST_PERSISTENT);
     255           17007 :         REGISTER_LONG_CONSTANT("SIGBABY",  (long) SIGSYS, CONST_CS | CONST_PERSISTENT);
     256                 : #endif
     257                 : 
     258                 : #if HAVE_GETPRIORITY || HAVE_SETPRIORITY
     259           17007 :         REGISTER_LONG_CONSTANT("PRIO_PGRP", PRIO_PGRP, CONST_CS | CONST_PERSISTENT);
     260           17007 :         REGISTER_LONG_CONSTANT("PRIO_USER", PRIO_USER, CONST_CS | CONST_PERSISTENT);
     261           17007 :         REGISTER_LONG_CONSTANT("PRIO_PROCESS", PRIO_PROCESS, CONST_CS | CONST_PERSISTENT);
     262                 : #endif
     263                 : 
     264                 :         /* {{{ "how" argument for sigprocmask */
     265                 : #ifdef HAVE_SIGPROCMASK
     266           17007 :         REGISTER_LONG_CONSTANT("SIG_BLOCK",   SIG_BLOCK, CONST_CS | CONST_PERSISTENT);
     267           17007 :         REGISTER_LONG_CONSTANT("SIG_UNBLOCK", SIG_UNBLOCK, CONST_CS | CONST_PERSISTENT);
     268           17007 :         REGISTER_LONG_CONSTANT("SIG_SETMASK", SIG_SETMASK, CONST_CS | CONST_PERSISTENT);
     269                 : #endif
     270                 :         /* }}} */
     271                 : 
     272                 :         /* {{{ si_code */
     273                 : #if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
     274           17007 :         REGISTER_LONG_CONSTANT("SI_USER",    SI_USER,    CONST_CS | CONST_PERSISTENT);
     275                 : #ifdef SI_NOINFO
     276                 :         REGISTER_LONG_CONSTANT("SI_NOINFO",  SI_NOINFO,  CONST_CS | CONST_PERSISTENT);
     277                 : #endif
     278                 : #ifdef SI_KERNEL
     279           17007 :         REGISTER_LONG_CONSTANT("SI_KERNEL",  SI_KERNEL,  CONST_CS | CONST_PERSISTENT);
     280                 : #endif
     281           17007 :         REGISTER_LONG_CONSTANT("SI_QUEUE",   SI_QUEUE,   CONST_CS | CONST_PERSISTENT);
     282           17007 :         REGISTER_LONG_CONSTANT("SI_TIMER",   SI_TIMER,   CONST_CS | CONST_PERSISTENT);
     283           17007 :         REGISTER_LONG_CONSTANT("SI_MESGQ",   SI_MESGQ,   CONST_CS | CONST_PERSISTENT);
     284           17007 :         REGISTER_LONG_CONSTANT("SI_ASYNCIO", SI_ASYNCIO, CONST_CS | CONST_PERSISTENT);
     285                 : #ifdef SI_SIGIO
     286           17007 :         REGISTER_LONG_CONSTANT("SI_SIGIO",   SI_SIGIO,   CONST_CS | CONST_PERSISTENT);
     287                 : #endif
     288                 : #ifdef SI_TKILL
     289           17007 :         REGISTER_LONG_CONSTANT("SI_TKILL",   SI_TKILL,   CONST_CS | CONST_PERSISTENT);
     290                 : #endif
     291                 : 
     292                 :         /* si_code for SIGCHILD */
     293                 : #ifdef CLD_EXITED
     294           17007 :         REGISTER_LONG_CONSTANT("CLD_EXITED",    CLD_EXITED,    CONST_CS | CONST_PERSISTENT);
     295                 : #endif
     296                 : #ifdef CLD_KILLED
     297           17007 :         REGISTER_LONG_CONSTANT("CLD_KILLED",    CLD_KILLED,    CONST_CS | CONST_PERSISTENT);
     298                 : #endif
     299                 : #ifdef CLD_DUMPED
     300           17007 :         REGISTER_LONG_CONSTANT("CLD_DUMPED",    CLD_DUMPED,    CONST_CS | CONST_PERSISTENT);
     301                 : #endif
     302                 : #ifdef CLD_TRAPPED
     303           17007 :         REGISTER_LONG_CONSTANT("CLD_TRAPPED",   CLD_TRAPPED,   CONST_CS | CONST_PERSISTENT);
     304                 : #endif
     305                 : #ifdef CLD_STOPPED
     306           17007 :         REGISTER_LONG_CONSTANT("CLD_STOPPED",   CLD_STOPPED,   CONST_CS | CONST_PERSISTENT);
     307                 : #endif
     308                 : #ifdef CLD_CONTINUED
     309           17007 :         REGISTER_LONG_CONSTANT("CLD_CONTINUED", CLD_CONTINUED, CONST_CS | CONST_PERSISTENT);
     310                 : #endif
     311                 : 
     312                 :         /* si_code for SIGTRAP */
     313                 : #ifdef TRAP_BRKPT
     314           17007 :         REGISTER_LONG_CONSTANT("TRAP_BRKPT", TRAP_BRKPT, CONST_CS | CONST_PERSISTENT);
     315                 : #endif
     316                 : #ifdef TRAP_TRACE
     317           17007 :         REGISTER_LONG_CONSTANT("TRAP_TRACE", TRAP_TRACE, CONST_CS | CONST_PERSISTENT);
     318                 : #endif
     319                 : 
     320                 :         /* si_code for SIGPOLL */
     321                 : #ifdef POLL_IN
     322           17007 :         REGISTER_LONG_CONSTANT("POLL_IN",  POLL_IN,  CONST_CS | CONST_PERSISTENT);
     323                 : #endif
     324                 : #ifdef POLL_OUT
     325           17007 :         REGISTER_LONG_CONSTANT("POLL_OUT", POLL_OUT, CONST_CS | CONST_PERSISTENT);
     326                 : #endif
     327                 : #ifdef POLL_MSG
     328           17007 :         REGISTER_LONG_CONSTANT("POLL_MSG", POLL_MSG, CONST_CS | CONST_PERSISTENT);
     329                 : #endif
     330                 : #ifdef POLL_ERR
     331           17007 :         REGISTER_LONG_CONSTANT("POLL_ERR", POLL_ERR, CONST_CS | CONST_PERSISTENT);
     332                 : #endif
     333                 : #ifdef POLL_PRI
     334           17007 :         REGISTER_LONG_CONSTANT("POLL_PRI", POLL_PRI, CONST_CS | CONST_PERSISTENT);
     335                 : #endif
     336                 : #ifdef POLL_HUP
     337           17007 :         REGISTER_LONG_CONSTANT("POLL_HUP", POLL_HUP, CONST_CS | CONST_PERSISTENT);
     338                 : #endif
     339                 : 
     340                 : #ifdef ILL_ILLOPC
     341           17007 :         REGISTER_LONG_CONSTANT("ILL_ILLOPC", ILL_ILLOPC, CONST_CS | CONST_PERSISTENT);
     342                 : #endif
     343                 : #ifdef ILL_ILLOPN
     344           17007 :         REGISTER_LONG_CONSTANT("ILL_ILLOPN", ILL_ILLOPN, CONST_CS | CONST_PERSISTENT);
     345                 : #endif
     346                 : #ifdef ILL_ILLADR
     347           17007 :         REGISTER_LONG_CONSTANT("ILL_ILLADR", ILL_ILLADR, CONST_CS | CONST_PERSISTENT);
     348                 : #endif
     349                 : #ifdef ILL_ILLTRP
     350           17007 :         REGISTER_LONG_CONSTANT("ILL_ILLTRP", ILL_ILLTRP, CONST_CS | CONST_PERSISTENT);
     351                 : #endif
     352                 : #ifdef ILL_PRVOPC
     353           17007 :         REGISTER_LONG_CONSTANT("ILL_PRVOPC", ILL_PRVOPC, CONST_CS | CONST_PERSISTENT);
     354                 : #endif
     355                 : #ifdef ILL_PRVREG
     356           17007 :         REGISTER_LONG_CONSTANT("ILL_PRVREG", ILL_PRVREG, CONST_CS | CONST_PERSISTENT);
     357                 : #endif
     358                 : #ifdef ILL_COPROC
     359           17007 :         REGISTER_LONG_CONSTANT("ILL_COPROC", ILL_COPROC, CONST_CS | CONST_PERSISTENT);
     360                 : #endif
     361                 : #ifdef ILL_BADSTK
     362           17007 :         REGISTER_LONG_CONSTANT("ILL_BADSTK", ILL_BADSTK, CONST_CS | CONST_PERSISTENT);
     363                 : #endif
     364                 : 
     365                 : #ifdef FPE_INTDIV
     366           17007 :         REGISTER_LONG_CONSTANT("FPE_INTDIV", FPE_INTDIV, CONST_CS | CONST_PERSISTENT);
     367                 : #endif
     368                 : #ifdef FPE_INTOVF
     369           17007 :         REGISTER_LONG_CONSTANT("FPE_INTOVF", FPE_INTOVF, CONST_CS | CONST_PERSISTENT);
     370                 : #endif
     371                 : #ifdef FPE_FLTDIV
     372           17007 :         REGISTER_LONG_CONSTANT("FPE_FLTDIV", FPE_FLTDIV, CONST_CS | CONST_PERSISTENT);
     373                 : #endif
     374                 : #ifdef FPE_FLTOVF
     375           17007 :         REGISTER_LONG_CONSTANT("FPE_FLTOVF", FPE_FLTOVF, CONST_CS | CONST_PERSISTENT);
     376                 : #endif
     377                 : #ifdef FPE_FLTUND
     378           17007 :         REGISTER_LONG_CONSTANT("FPE_FLTUND", FPE_FLTINV, CONST_CS | CONST_PERSISTENT);
     379                 : #endif
     380                 : #ifdef FPE_FLTRES
     381           17007 :         REGISTER_LONG_CONSTANT("FPE_FLTRES", FPE_FLTRES, CONST_CS | CONST_PERSISTENT);
     382                 : #endif
     383                 : #ifdef FPE_FLTINV
     384           17007 :         REGISTER_LONG_CONSTANT("FPE_FLTINV", FPE_FLTINV, CONST_CS | CONST_PERSISTENT);
     385                 : #endif
     386                 : #ifdef FPE_FLTSUB
     387           17007 :         REGISTER_LONG_CONSTANT("FPE_FLTSUB", FPE_FLTSUB, CONST_CS | CONST_PERSISTENT);
     388                 : #endif
     389                 : 
     390                 : #ifdef SEGV_MAPERR
     391           17007 :         REGISTER_LONG_CONSTANT("SEGV_MAPERR", SEGV_MAPERR, CONST_CS | CONST_PERSISTENT);
     392                 : #endif
     393                 : #ifdef SEGV_ACCERR
     394           17007 :         REGISTER_LONG_CONSTANT("SEGV_ACCERR", SEGV_ACCERR, CONST_CS | CONST_PERSISTENT);
     395                 : #endif
     396                 : 
     397                 : #ifdef BUS_ADRALN
     398           17007 :         REGISTER_LONG_CONSTANT("BUS_ADRALN", BUS_ADRALN, CONST_CS | CONST_PERSISTENT);
     399                 : #endif
     400                 : #ifdef BUS_ADRERR
     401           17007 :         REGISTER_LONG_CONSTANT("BUS_ADRERR", BUS_ADRERR, CONST_CS | CONST_PERSISTENT);
     402                 : #endif
     403                 : #ifdef BUS_OBJERR
     404           17007 :         REGISTER_LONG_CONSTANT("BUS_OBJERR", BUS_OBJERR, CONST_CS | CONST_PERSISTENT);
     405                 : #endif
     406                 : #endif /* HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT */
     407                 :         /* }}} */
     408           17007 : }
     409                 : 
     410                 : static PHP_GINIT_FUNCTION(pcntl)
     411           17007 : { 
     412           17007 :         memset(pcntl_globals, 0, sizeof(*pcntl_globals));
     413           17007 : }
     414                 : 
     415                 : PHP_RINIT_FUNCTION(pcntl)
     416           16993 : {
     417           16993 :         zend_hash_init(&PCNTL_G(php_signal_table), 16, NULL, ZVAL_PTR_DTOR, 0);
     418           16993 :         PCNTL_G(head) = PCNTL_G(tail) = PCNTL_G(spares) = NULL;
     419           16993 :         return SUCCESS;
     420                 : }
     421                 : 
     422                 : PHP_MINIT_FUNCTION(pcntl)
     423           17007 : {
     424           17007 :         php_register_signal_constants(INIT_FUNC_ARGS_PASSTHRU);
     425           17007 :         php_add_tick_function(pcntl_signal_dispatch);
     426                 : 
     427           17007 :         return SUCCESS;
     428                 : }
     429                 : 
     430                 : PHP_MSHUTDOWN_FUNCTION(pcntl)
     431           17039 : {
     432           17039 :         return SUCCESS;
     433                 : }
     434                 : 
     435                 : PHP_RSHUTDOWN_FUNCTION(pcntl)
     436           17025 : {
     437                 :         struct php_pcntl_pending_signal *sig;
     438                 : 
     439                 :         /* FIXME: if a signal is delivered after this point, things will go pear shaped;
     440                 :          * need to remove signal handlers */
     441           17025 :         zend_hash_destroy(&PCNTL_G(php_signal_table));
     442           34051 :         while (PCNTL_G(head)) {
     443               1 :                 sig = PCNTL_G(head);
     444               1 :                 PCNTL_G(head) = sig->next;
     445               1 :                 efree(sig);
     446                 :         }
     447           34209 :         while (PCNTL_G(spares)) {
     448             159 :                 sig = PCNTL_G(spares);
     449             159 :                 PCNTL_G(spares) = sig->next;
     450             159 :                 efree(sig);
     451                 :         }
     452           17025 :         return SUCCESS;
     453                 : }
     454                 : 
     455                 : PHP_MINFO_FUNCTION(pcntl)
     456              43 : {
     457              43 :         php_info_print_table_start();
     458              43 :         php_info_print_table_header(2, "pcntl support", "enabled");
     459              43 :         php_info_print_table_end();
     460              43 : }
     461                 : 
     462                 : /* {{{ proto int pcntl_fork(void) U
     463                 :    Forks the currently running process following the same behavior as the UNIX fork() system call*/
     464                 : PHP_FUNCTION(pcntl_fork)
     465              54 : {
     466                 :         pid_t id;
     467                 : 
     468              54 :         id = fork();
     469              93 :         if (id == -1) {
     470               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d", errno);
     471                 :         }
     472                 :         
     473              93 :         RETURN_LONG((long) id);
     474                 : }
     475                 : /* }}} */
     476                 : 
     477                 : /* {{{ proto int pcntl_alarm(int seconds) U
     478                 :    Set an alarm clock for delivery of a signal*/
     479                 : PHP_FUNCTION(pcntl_alarm)
     480              17 : {
     481                 :         long seconds;
     482                 : 
     483              17 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &seconds) == FAILURE)
     484               1 :                 return;
     485                 :         
     486              16 :         RETURN_LONG ((long) alarm(seconds));
     487                 : }
     488                 : /* }}} */
     489                 : 
     490                 : /* {{{ proto int pcntl_waitpid(int pid, int &status, int options) U
     491                 :    Waits on or returns the status of a forked child as defined by the waitpid() system call */
     492                 : PHP_FUNCTION(pcntl_waitpid)
     493              44 : {
     494              44 :         long pid, options = 0;
     495              44 :         zval *z_status = NULL;
     496                 :         int status;
     497                 :         pid_t child_id;
     498                 : 
     499              44 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|l", &pid, &z_status, &options) == FAILURE)
     500               1 :                 return;
     501                 :         
     502              43 :         convert_to_long_ex(&z_status);
     503                 : 
     504              43 :         status = Z_LVAL_P(z_status);
     505                 : 
     506              43 :         child_id = waitpid((pid_t) pid, &status, options);
     507                 : 
     508              43 :         Z_LVAL_P(z_status) = status;
     509                 : 
     510              43 :         RETURN_LONG((long) child_id);
     511                 : }
     512                 : /* }}} */
     513                 : 
     514                 : /* {{{ proto int pcntl_wait(int &status) U
     515                 :    Waits on or returns the status of a forked child as defined by the waitpid() system call */
     516                 : PHP_FUNCTION(pcntl_wait)
     517               7 : {
     518               7 :         long options = 0;
     519               7 :         zval *z_status = NULL;
     520                 :         int status;
     521                 :         pid_t child_id;
     522                 : 
     523               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &z_status, &options) == FAILURE)
     524               1 :                 return;
     525                 :         
     526               6 :         convert_to_long_ex(&z_status);
     527                 : 
     528               6 :         status = Z_LVAL_P(z_status);
     529                 : #ifdef HAVE_WAIT3
     530               6 :         if(options) {
     531               2 :                 child_id = wait3(&status, options, NULL);
     532                 :         }
     533                 :         else {
     534               4 :                 child_id = wait(&status);
     535                 :         }
     536                 : #else
     537                 :         child_id = wait(&status);
     538                 : #endif
     539               6 :         Z_LVAL_P(z_status) = status;
     540                 : 
     541               6 :         RETURN_LONG((long) child_id);
     542                 : }
     543                 : /* }}} */
     544                 : 
     545                 : /* {{{ proto bool pcntl_wifexited(int status)  U
     546                 :    Returns true if the child status code represents a successful exit */
     547                 : PHP_FUNCTION(pcntl_wifexited)
     548               5 : {
     549                 : #ifdef WIFEXITED
     550                 :         long status_word;
     551                 : 
     552               5 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &status_word) == FAILURE) {
     553               1 :                return;
     554                 :         }
     555                 : 
     556               4 :         if (WIFEXITED(status_word))
     557               3 :                 RETURN_TRUE;
     558                 : #endif
     559               1 :         RETURN_FALSE;
     560                 : }
     561                 : /* }}} */
     562                 : 
     563                 : /* {{{ proto bool pcntl_wifstopped(int status)  U
     564                 :    Returns true if the child status code represents a stopped process (WUNTRACED must have been used with waitpid) */
     565                 : PHP_FUNCTION(pcntl_wifstopped)
     566               3 : {
     567                 : #ifdef WIFSTOPPED
     568                 :         long status_word;
     569                 : 
     570               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &status_word) == FAILURE) {
     571               1 :                return;
     572                 :         }
     573                 : 
     574               2 :         if (WIFSTOPPED(status_word))
     575               1 :                 RETURN_TRUE;
     576                 : #endif
     577               1 :         RETURN_FALSE;
     578                 : }
     579                 : /* }}} */
     580                 : 
     581                 : /* {{{ proto bool pcntl_wifsignaled(int status) U
     582                 :    Returns true if the child status code represents a process that was terminated due to a signal */
     583                 : PHP_FUNCTION(pcntl_wifsignaled)
     584               3 : {
     585                 : #ifdef WIFSIGNALED
     586                 :         long status_word;
     587                 : 
     588               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &status_word) == FAILURE) {
     589               1 :                return;
     590                 :         }
     591                 : 
     592               2 :         if (WIFSIGNALED(status_word))
     593               1 :                 RETURN_TRUE;
     594                 : #endif
     595               1 :         RETURN_FALSE;
     596                 : }
     597                 : /* }}} */
     598                 : 
     599                 : /* {{{ proto int pcntl_wexitstatus(int status) U
     600                 :    Returns the status code of a child's exit */
     601                 : PHP_FUNCTION(pcntl_wexitstatus)
     602               6 : {
     603                 : #ifdef WEXITSTATUS
     604                 :         long status_word;
     605                 : 
     606               6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &status_word) == FAILURE) {
     607               1 :                return;
     608                 :         }
     609                 : 
     610               5 :         RETURN_LONG(WEXITSTATUS(status_word));
     611                 : #else
     612                 :         RETURN_FALSE;
     613                 : #endif
     614                 : }
     615                 : /* }}} */
     616                 : 
     617                 : /* {{{ proto int pcntl_wtermsig(int status) U
     618                 :    Returns the number of the signal that terminated the process who's status code is passed  */
     619                 : PHP_FUNCTION(pcntl_wtermsig)
     620               2 : {
     621                 : #ifdef WTERMSIG
     622                 :         long status_word;
     623                 : 
     624               2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &status_word) == FAILURE) {
     625               1 :                return;
     626                 :         }
     627                 : 
     628               1 :         RETURN_LONG(WTERMSIG(status_word));
     629                 : #else
     630                 :         RETURN_FALSE;
     631                 : #endif
     632                 : }
     633                 : /* }}} */
     634                 : 
     635                 : /* {{{ proto int pcntl_wstopsig(int status) U
     636                 :    Returns the number of the signal that caused the process to stop who's status code is passed */
     637                 : PHP_FUNCTION(pcntl_wstopsig)
     638               2 : {
     639                 : #ifdef WSTOPSIG
     640                 :         long status_word;
     641                 : 
     642               2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &status_word) == FAILURE) {
     643               1 :                return;
     644                 :         }
     645                 : 
     646               1 :         RETURN_LONG(WSTOPSIG(status_word));
     647                 : #else
     648                 :         RETURN_FALSE;
     649                 : #endif
     650                 : }
     651                 : /* }}} */
     652                 : 
     653                 : /* {{{ proto bool pcntl_exec(string path [, array args [, array envs]])
     654                 :    Executes specified program in current process space as defined by exec(2) */
     655                 : PHP_FUNCTION(pcntl_exec)
     656               4 : {
     657               4 :         zval *args = NULL, *envs = NULL;
     658                 :         zval **element;
     659                 :         HashTable *args_hash, *envs_hash;
     660               4 :         int argc = 0, argi = 0;
     661               4 :         int envc = 0, envi = 0;
     662               4 :         int return_val = 0;
     663               4 :         char **argv = NULL, **envp = NULL;
     664                 :         char **current_arg, **pair;
     665                 :         int pair_length;
     666                 :         char *key;
     667                 :         uint key_length;
     668                 :         char *path;
     669                 :         int path_len;
     670                 :         ulong key_num;
     671                 :                 
     672               4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|aa", &path, &path_len, &args, &envs) == FAILURE) {
     673               1 :                 return;
     674                 :         }
     675                 :         
     676               3 :         if (ZEND_NUM_ARGS() > 1) {
     677                 :                 /* Build argumnent list */
     678               2 :                 args_hash = HASH_OF(args);
     679               2 :                 argc = zend_hash_num_elements(args_hash);
     680                 :                 
     681               2 :                 argv = safe_emalloc((argc + 2), sizeof(char *), 0);
     682               2 :                 *argv = path;
     683               2 :                 for ( zend_hash_internal_pointer_reset(args_hash), current_arg = argv+1; 
     684               7 :                         (argi < argc && (zend_hash_get_current_data(args_hash, (void **) &element) == SUCCESS));
     685               3 :                         (argi++, current_arg++, zend_hash_move_forward(args_hash)) ) {
     686                 : 
     687               3 :                         convert_to_string_ex(element);
     688               3 :                         *current_arg = Z_STRVAL_PP(element);
     689                 :                 }
     690               2 :                 *(current_arg) = NULL;
     691                 :         } else {
     692               1 :                 argv = emalloc(2 * sizeof(char *));
     693               1 :                 *argv = path;
     694               1 :                 *(argv+1) = NULL;
     695                 :         }
     696                 : 
     697               3 :         if ( ZEND_NUM_ARGS() == 3 ) {
     698                 :                 /* Build environment pair list */
     699               2 :                 envs_hash = HASH_OF(envs);
     700               2 :                 envc = zend_hash_num_elements(envs_hash);
     701                 :                 
     702               2 :                 envp = safe_emalloc((envc + 1), sizeof(char *), 0);
     703               2 :                 for ( zend_hash_internal_pointer_reset(envs_hash), pair = envp; 
     704               8 :                         (envi < envc && (zend_hash_get_current_data(envs_hash, (void **) &element) == SUCCESS));
     705               4 :                         (envi++, pair++, zend_hash_move_forward(envs_hash)) ) {
     706               4 :                         switch (return_val = zend_hash_get_current_key_ex(envs_hash, &key, &key_length, &key_num, 0, NULL)) {
     707                 :                                 case HASH_KEY_IS_LONG:
     708               1 :                                         key = emalloc(101);
     709               1 :                                         snprintf(key, 100, "%ld", key_num);
     710               1 :                                         key_length = strlen(key);
     711               1 :                                         break;
     712                 :                                 case HASH_KEY_NON_EXISTANT:
     713               0 :                                         pair--;
     714               0 :                                         continue;
     715                 :                         }
     716                 : 
     717               4 :                         convert_to_string_ex(element);
     718                 : 
     719                 :                         /* Length of element + equal sign + length of key + null */ 
     720               4 :                         pair_length = Z_STRLEN_PP(element) + key_length + 2;
     721               4 :                         *pair = emalloc(pair_length);
     722               4 :                         strlcpy(*pair, key, key_length); 
     723               4 :                         strlcat(*pair, "=", pair_length);
     724               4 :                         strlcat(*pair, Z_STRVAL_PP(element), pair_length);
     725                 :                         
     726                 :                         /* Cleanup */
     727               4 :                         if (return_val == HASH_KEY_IS_LONG) efree(key);
     728                 :                 }
     729               2 :                 *(pair) = NULL;
     730                 : 
     731               2 :                 if (execve(path, argv, envp) == -1) {
     732               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error has occured: (errno %d) %s", errno, strerror(errno));
     733                 :                 }
     734                 : 
     735                 :                 /* Cleanup */
     736               1 :                 for (pair = envp; *pair != NULL; pair++) efree(*pair);
     737               1 :                 efree(envp);
     738                 :         } else {
     739                 : 
     740               1 :                 if (execv(path, argv) == -1) {
     741               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error has occured: (errno %d) %s", errno, strerror(errno));
     742                 :                 }
     743                 :         }
     744                 :         
     745               1 :         efree(argv);
     746                 :         
     747               1 :         RETURN_FALSE;
     748                 : }
     749                 : /* }}} */
     750                 : 
     751                 : /* {{{ proto bool pcntl_signal(int signo, callback handle [, bool restart_syscalls]) U
     752                 :    Assigns a system signal handler to a PHP function */
     753                 : PHP_FUNCTION(pcntl_signal)
     754              10 : {
     755              10 :         zval *handle, **dest_handle = NULL;
     756                 :         zval func_name;
     757                 :         long signo;
     758              10 :         zend_bool restart_syscalls = 1;
     759                 : 
     760              10 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|b", &signo, &handle, &restart_syscalls) == FAILURE) {
     761               1 :                 return;
     762                 :         }
     763                 : 
     764               9 :         if (!PCNTL_G(spares)) {
     765                 :                 /* since calling malloc() from within a signal handler is not portable,
     766                 :                  * pre-allocate a few records for recording signals */
     767                 :                 int i;
     768             165 :                 for (i = 0; i < 32; i++) {
     769                 :                         struct php_pcntl_pending_signal *psig;
     770                 : 
     771             160 :                         psig = emalloc(sizeof(*psig));
     772             160 :                         psig->next = PCNTL_G(spares);
     773             160 :                         PCNTL_G(spares) = psig;
     774                 :                 }
     775                 :         }
     776                 : 
     777                 :         /* Special long value case for SIG_DFL and SIG_IGN */
     778               9 :         if (Z_TYPE_P(handle)==IS_LONG) {
     779               2 :                 if (Z_LVAL_P(handle)!= (long) SIG_DFL && Z_LVAL_P(handle) != (long) SIG_IGN) {
     780               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for handle argument specified");
     781                 :                 }
     782               2 :                 if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), (int) restart_syscalls) == SIG_ERR) {
     783               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error assigning signal");
     784               1 :                         RETURN_FALSE;
     785                 :                 }
     786               1 :                 RETURN_TRUE;
     787                 :         }
     788                 :         
     789               7 :         if (!zend_is_callable(handle, 0, &func_name TSRMLS_CC)) {
     790               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%R is not a callable function name error", Z_TYPE(func_name), Z_UNIVAL(func_name));
     791               1 :                 zval_dtor(&func_name);
     792               1 :                 RETURN_FALSE;
     793                 :         }
     794               6 :         zval_dtor(&func_name);
     795                 :         
     796                 :         /* Add the function name to our signal table */
     797               6 :         zend_hash_index_update(&PCNTL_G(php_signal_table), signo, (void **) &handle, sizeof(zval *), (void **) &dest_handle);
     798               6 :         if (dest_handle) zval_add_ref(dest_handle);
     799                 :         
     800               6 :         if (php_signal(signo, pcntl_signal_handler, (int) restart_syscalls) == SIG_ERR) {
     801               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error assigning signal");
     802               1 :                 RETURN_FALSE;
     803                 :         }
     804               5 :         RETURN_TRUE;
     805                 : }
     806                 : /* }}} */
     807                 : 
     808                 : /* {{{ proto bool pcntl_signal_dispatch()
     809                 :    Dispatch signals to signal handlers */
     810                 : PHP_FUNCTION(pcntl_signal_dispatch)
     811               2 : {
     812               2 :         pcntl_signal_dispatch();
     813               2 :         RETURN_TRUE;
     814                 : }
     815                 : /* }}} */
     816                 : 
     817                 : #ifdef HAVE_SIGPROCMASK
     818                 : /* {{{ proto bool pcntl_sigprocmask(int how, array set[, array &oldset])
     819                 :    Examine and change blocked signals */
     820                 : PHP_FUNCTION(pcntl_sigprocmask)
     821               9 : {
     822                 :         long          how, signo;
     823               9 :         zval         *user_set, *user_oldset = NULL, **user_signo;
     824                 :         sigset_t      set, oldset;
     825                 :         HashPosition  pos;
     826                 : 
     827               9 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "la|z", &how, &user_set, &user_oldset) == FAILURE) {
     828               0 :                 return;
     829                 :         }
     830                 : 
     831               9 :         if (sigemptyset(&set) != 0 || sigemptyset(&oldset) != 0) {
     832               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
     833               0 :                 RETURN_FALSE;
     834                 :         }
     835                 : 
     836               9 :         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(user_set), &pos);
     837              25 :         while (zend_hash_get_current_data_ex(Z_ARRVAL_P(user_set), (void **)&user_signo, &pos) == SUCCESS)
     838                 :         {
     839               8 :                 if (Z_TYPE_PP(user_signo) != IS_LONG) {
     840               1 :                         SEPARATE_ZVAL(user_signo);
     841               1 :                         convert_to_long_ex(user_signo);
     842                 :                 }
     843               8 :                 signo = Z_LVAL_PP(user_signo);
     844               8 :                 if (sigaddset(&set, signo) != 0) {
     845               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
     846               1 :                         RETURN_FALSE;
     847                 :                 }
     848               7 :                 zend_hash_move_forward_ex(Z_ARRVAL_P(user_set), &pos);
     849                 :         }
     850                 : 
     851               8 :         if (sigprocmask(how, &set, &oldset) != 0) {
     852               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
     853               0 :                 RETURN_FALSE;
     854                 :         }
     855                 : 
     856               8 :         if (user_oldset != NULL) {
     857               7 :                 if (Z_TYPE_P(user_oldset) != IS_ARRAY) {
     858               1 :                         zval_dtor(user_oldset);
     859               1 :                         array_init(user_oldset);
     860                 :                 } else {
     861               6 :                         zend_hash_clean(Z_ARRVAL_P(user_oldset));
     862                 :                 }
     863             448 :                 for (signo = 1; signo < MAX(NSIG-1, SIGRTMAX); ++signo) {
     864             441 :                         if (sigismember(&oldset, signo) != 1) {
     865             431 :                                 continue;
     866                 :                         }
     867              10 :                         add_next_index_long(user_oldset, signo);
     868                 :                 }
     869                 :         }
     870                 : 
     871               8 :         RETURN_TRUE;
     872                 : }
     873                 : /* }}} */
     874                 : #endif
     875                 : 
     876                 : #if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
     877                 : static void pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAMETERS, int timedwait) /* {{{ */
     878               5 : {
     879               5 :         zval            *user_set, **user_signo, *user_siginfo = NULL;
     880               5 :         long             tv_sec = 0, tv_nsec = 0;
     881                 :         sigset_t         set;
     882                 :         HashPosition     pos;
     883                 :         int              signo;
     884                 :         siginfo_t        siginfo;
     885                 :         struct timespec  timeout;
     886                 : 
     887               5 :         if (timedwait) {
     888               2 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zll", &user_set, &user_siginfo, &tv_sec, &tv_nsec) == FAILURE) {
     889               0 :                         return;
     890                 :                 }
     891                 :         } else {
     892               3 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &user_set, &user_siginfo) == FAILURE) {
     893               0 :                         return;
     894                 :                 }
     895                 :         }
     896                 : 
     897               5 :         if (sigemptyset(&set) != 0) {
     898               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
     899               0 :                 RETURN_FALSE;
     900                 :         }
     901                 : 
     902               5 :         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(user_set), &pos);
     903              14 :         while (zend_hash_get_current_data_ex(Z_ARRVAL_P(user_set), (void **)&user_signo, &pos) == SUCCESS)
     904                 :         {
     905               5 :                 if (Z_TYPE_PP(user_signo) != IS_LONG) {
     906               1 :                         SEPARATE_ZVAL(user_signo);
     907               1 :                         convert_to_long_ex(user_signo);
     908                 :                 }
     909               5 :                 signo = Z_LVAL_PP(user_signo);
     910               5 :                 if (sigaddset(&set, signo) != 0) {
     911               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
     912               1 :                         RETURN_FALSE;
     913                 :                 }
     914               4 :                 zend_hash_move_forward_ex(Z_ARRVAL_P(user_set), &pos);
     915                 :         }
     916                 : 
     917               4 :         if (timedwait) {
     918               2 :                 timeout.tv_sec  = (time_t) tv_sec;
     919               2 :                 timeout.tv_nsec = tv_nsec;
     920               2 :                 signo = sigtimedwait(&set, &siginfo, &timeout);
     921                 :         } else {
     922               2 :                 signo = sigwaitinfo(&set, &siginfo);
     923                 :         }
     924               4 :         if (signo == -1 && errno != EAGAIN) {
     925               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
     926                 :         }
     927                 : 
     928                 :         /*
     929                 :          * sigtimedwait and sigwaitinfo can return 0 on success on some 
     930                 :          * platforms, e.g. NetBSD
     931                 :          */
     932               4 :         if (!signo && siginfo.si_signo) {
     933               0 :                 signo = siginfo.si_signo;
     934                 :         }
     935                 : 
     936               4 :         if (signo > 0 && user_siginfo) {
     937               3 :                 if (Z_TYPE_P(user_siginfo) != IS_ARRAY) {
     938               1 :                         zval_dtor(user_siginfo);
     939               1 :                         array_init(user_siginfo);
     940                 :                 } else {
     941               2 :                         zend_hash_clean(Z_ARRVAL_P(user_siginfo));
     942                 :                 }
     943               3 :                 add_ascii_assoc_long_ex(user_siginfo, "signo", sizeof("signo"), siginfo.si_signo);
     944               3 :                 add_ascii_assoc_long_ex(user_siginfo, "errno", sizeof("errno"), siginfo.si_errno);
     945               3 :                 add_ascii_assoc_long_ex(user_siginfo, "code",  sizeof("code"),  siginfo.si_code);
     946               3 :                 switch(signo) {
     947                 : #ifdef SIGCHLD
     948                 :                         case SIGCHLD:
     949               1 :                                 add_ascii_assoc_long_ex(user_siginfo,   "status", sizeof("status"), siginfo.si_status);
     950                 : # ifdef si_utime
     951               1 :                                 add_ascii_assoc_double_ex(user_siginfo, "utime",  sizeof("utime"),  siginfo.si_utime);
     952                 : # endif
     953                 : # ifdef si_stime
     954               1 :                                 add_ascii_assoc_double_ex(user_siginfo, "stime",  sizeof("stime"),  siginfo.si_stime);
     955                 : # endif
     956               1 :                                 add_ascii_assoc_long_ex(user_siginfo,   "pid",    sizeof("pid"),    siginfo.si_pid);
     957               1 :                                 add_ascii_assoc_long_ex(user_siginfo,   "uid",    sizeof("uid"),    siginfo.si_uid);
     958               1 :                                 break;
     959                 : #endif
     960                 :                         case SIGILL:
     961                 :                         case SIGFPE:
     962                 :                         case SIGSEGV:
     963                 :                         case SIGBUS:
     964               0 :                                 add_ascii_assoc_double_ex(user_siginfo, "addr", sizeof("addr"), (long)siginfo.si_addr);
     965               0 :                                 break;
     966                 : #ifdef SIGPOLL
     967                 :                         case SIGPOLL:
     968               0 :                                 add_ascii_assoc_long_ex(user_siginfo, "band", sizeof("band"), siginfo.si_band);
     969                 : #ifdef si_fd
     970               0 :                                 add_ascii_assoc_long_ex(user_siginfo, "fd",   sizeof("fd"),   siginfo.si_fd);
     971                 : #endif
     972                 :                                 break;
     973                 : #endif
     974                 :                         EMPTY_SWITCH_DEFAULT_CASE();
     975                 :                 }
     976                 :         }
     977                 :         
     978               4 :         RETURN_LONG(signo);
     979                 : }
     980                 : /* }}} */
     981                 : 
     982                 : /* {{{ proto int pcnlt_sigwaitinfo(array set[, array &siginfo])
     983                 :    Synchronously wait for queued signals */
     984                 : PHP_FUNCTION(pcntl_sigwaitinfo)
     985               3 : {
     986               3 :         pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     987               3 : }
     988                 : /* }}} */
     989                 : 
     990                 : /* {{{ proto int pcntl_sigtimedwait(array set[, array &siginfo[, int seconds[, int nanoseconds]]])
     991                 :    Wait for queued signals */
     992                 : PHP_FUNCTION(pcntl_sigtimedwait)
     993               2 : {
     994               2 :         pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     995               2 : }
     996                 : /* }}} */
     997                 : #endif
     998                 : 
     999                 : #ifdef HAVE_GETPRIORITY
    1000                 : /* {{{ proto int pcntl_getpriority([int pid [, int process_identifier]]) U
    1001                 :    Get the priority of any process */
    1002                 : PHP_FUNCTION(pcntl_getpriority)
    1003               0 : {
    1004               0 :         long who = PRIO_PROCESS;
    1005               0 :         long pid = getpid();
    1006                 :         int pri;
    1007                 :         
    1008               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &pid, &who) == FAILURE) {
    1009               0 :                 RETURN_FALSE;
    1010                 :         }
    1011                 : 
    1012                 :         /* needs to be cleared, since any returned value is valid */ 
    1013               0 :         errno = 0;
    1014                 : 
    1015               0 :         pri = getpriority(who, pid);
    1016                 : 
    1017               0 :         if (errno) {
    1018               0 :                 switch (errno) {
    1019                 :                         case ESRCH:
    1020               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d: No process was located using the given parameters", errno);
    1021               0 :                                 break;
    1022                 :                         case EINVAL:
    1023               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d: Invalid identifier flag", errno);
    1024               0 :                                 break;
    1025                 :                         default:
    1026               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error %d has occured", errno);
    1027                 :                                 break;
    1028                 :                 }
    1029               0 :                 RETURN_FALSE;
    1030                 :         }
    1031                 : 
    1032               0 :         RETURN_LONG(pri);
    1033                 : }
    1034                 : /* }}} */
    1035                 : #endif
    1036                 : 
    1037                 : #ifdef HAVE_SETPRIORITY
    1038                 : /* {{{ proto bool pcntl_setpriority(int priority [, int pid [, int process_identifier]]) U
    1039                 :    Change the priority of any process */
    1040                 : PHP_FUNCTION(pcntl_setpriority)
    1041               0 : {
    1042               0 :         long who = PRIO_PROCESS;
    1043               0 :         long pid = getpid();
    1044                 :         long pri;
    1045                 : 
    1046               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &pri, &pid, &who) == FAILURE) {
    1047               0 :                 RETURN_FALSE;
    1048                 :         }
    1049                 : 
    1050               0 :         if (setpriority(who, pid, pri)) {
    1051               0 :                 switch (errno) {
    1052                 :                         case ESRCH:
    1053               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d: No process was located using the given parameters", errno);
    1054               0 :                                 break;
    1055                 :                         case EINVAL:
    1056               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d: Invalid identifier flag", errno);
    1057               0 :                                 break;
    1058                 :                         case EPERM:
    1059               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d: A process was located, but neither its effective nor real user ID matched the effective user ID of the caller", errno);
    1060               0 :                                 break;
    1061                 :                         case EACCES:
    1062               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d: Only a super user may attempt to increase the process priority", errno);
    1063               0 :                                 break;
    1064                 :                         default:
    1065               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error %d has occured", errno);
    1066                 :                                 break;
    1067                 :                 }
    1068               0 :                 RETURN_FALSE;
    1069                 :         }
    1070                 :         
    1071               0 :         RETURN_TRUE;
    1072                 : }
    1073                 : /* }}} */
    1074                 : #endif
    1075                 : 
    1076                 : /* Our custom signal handler that calls the appropriate php_function */
    1077                 : static void pcntl_signal_handler(int signo)
    1078               4 : {
    1079                 :         struct php_pcntl_pending_signal *psig;
    1080                 :         TSRMLS_FETCH();
    1081                 :         
    1082               4 :         psig = PCNTL_G(spares);
    1083               4 :         if (!psig) {
    1084                 :                 /* oops, too many signals for us to track, so we'll forget about this one */
    1085               0 :                 return;
    1086                 :         }
    1087               4 :         PCNTL_G(spares) = psig->next;
    1088                 : 
    1089               4 :         psig->signo = signo;
    1090               4 :         psig->next = NULL;
    1091                 : 
    1092                 :         /* the head check is important, as the tick handler cannot atomically clear both
    1093                 :          * the head and tail */
    1094               4 :         if (PCNTL_G(head) && PCNTL_G(tail)) {
    1095               0 :                 PCNTL_G(tail)->next = psig;
    1096                 :         } else {
    1097               4 :                 PCNTL_G(head) = psig;
    1098                 :         }
    1099               4 :         PCNTL_G(tail) = psig;
    1100                 : }
    1101                 : 
    1102                 : void pcntl_signal_dispatch()
    1103              40 : {
    1104                 :         zval *param, **handle, *retval;
    1105                 :         struct php_pcntl_pending_signal *queue, *next;
    1106                 :         TSRMLS_FETCH();
    1107                 : 
    1108                 :         /* Bail if the queue is empty or if we are already playing the queue*/
    1109              40 :         if (! PCNTL_G(head) || PCNTL_G(processing_signal_queue))
    1110              37 :                 return;
    1111                 : 
    1112                 :         /* Prevent reentrant handler calls */
    1113               3 :         PCNTL_G(processing_signal_queue) = 1;
    1114                 : 
    1115               3 :         queue = PCNTL_G(head);
    1116               3 :         PCNTL_G(head) = NULL; /* simple stores are atomic */
    1117                 :         
    1118                 :         /* Allocate */
    1119                 : 
    1120               9 :         while (queue) {
    1121               3 :                 if (zend_hash_index_find(&PCNTL_G(php_signal_table), queue->signo, (void **) &handle)==SUCCESS) {
    1122               3 :                         MAKE_STD_ZVAL(retval);
    1123               3 :                         MAKE_STD_ZVAL(param);
    1124               3 :                         ZVAL_NULL(retval);
    1125               3 :                         ZVAL_LONG(param, queue->signo);
    1126                 : 
    1127                 :                         /* Call php signal handler - Note that we do not report errors, and we ignore the return value */
    1128                 :                         /* FIXME: this is probably broken when multiple signals are handled in this while loop (retval) */
    1129               3 :                         call_user_function(EG(function_table), NULL, *handle, retval, 1, &param TSRMLS_CC);
    1130               3 :                         zval_ptr_dtor(&param);
    1131               3 :                         zval_ptr_dtor(&retval);
    1132                 :                 }
    1133                 : 
    1134               3 :                 next = queue->next;
    1135               3 :                 queue->next = PCNTL_G(spares);
    1136               3 :                 PCNTL_G(spares) = queue;
    1137               3 :                 queue = next;
    1138                 :         }
    1139                 : 
    1140                 :         /* Re-enable queue */
    1141               3 :         PCNTL_G(processing_signal_queue) = 0;
    1142                 : }
    1143                 : 
    1144                 : 
    1145                 : 
    1146                 : /*
    1147                 :  * Local variables:
    1148                 :  * tab-width: 4
    1149                 :  * c-basic-offset: 4
    1150                 :  * indent-tabs-mode: t
    1151                 :  * End:
    1152                 :  */

Generated by: LTP GCOV extension version 1.5

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

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