2001-06-12 16:54:25 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 16:18:22 +08:00
| PHP Version 5 |
2001-06-12 16:54:25 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2012-01-01 21:15:04 +08:00
| Copyright ( c ) 1997 - 2012 The PHP Group |
2001-06-12 16:54:25 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
2001-06-12 16:54:25 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
2001-06-12 16:54:25 +08:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2002-02-28 16:29:35 +08:00
| Author : Jason Greene < jason @ inetgurus . net > |
2001-06-12 16:54:25 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2001-07-31 04:51:57 +08:00
/* $Id$ */
2001-06-20 05:42:57 +08:00
# define PCNTL_DEBUG 0
# if PCNTL_DEBUG
# define DEBUG_OUT printf("DEBUG: ");printf
2002-08-22 12:20:10 +08:00
# define IF_DEBUG(z) z
2001-06-20 05:42:57 +08:00
# else
2002-08-22 12:20:10 +08:00
# define IF_DEBUG(z)
2001-06-20 05:42:57 +08:00
# endif
2001-06-12 16:54:25 +08:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "php.h"
# include "php_ini.h"
2002-03-17 16:10:04 +08:00
# include "ext/standard/info.h"
2001-06-12 16:54:25 +08:00
# include "php_pcntl.h"
2008-08-05 23:12:19 +08:00
# include "php_signal.h"
# include "php_ticks.h"
2001-06-12 16:54:25 +08:00
2003-10-29 01:08:18 +08:00
# if HAVE_GETPRIORITY || HAVE_SETPRIORITY || HAVE_WAIT3
2008-08-05 23:12:19 +08:00
# include <sys/wait.h>
2003-02-18 09:41:06 +08:00
# include <sys/time.h>
# include <sys/resource.h>
# endif
2010-11-02 04:22:23 +08:00
# include <errno.h>
2001-06-12 16:54:25 +08:00
ZEND_DECLARE_MODULE_GLOBALS ( pcntl )
2006-06-16 02:33:09 +08:00
static PHP_GINIT_FUNCTION ( pcntl ) ;
2001-06-12 16:54:25 +08:00
2008-06-30 21:15:03 +08:00
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO ( arginfo_pcntl_void , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_waitpid , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , pid )
ZEND_ARG_INFO ( 1 , status )
ZEND_ARG_INFO ( 0 , options )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_wait , 0 , 0 , 1 )
ZEND_ARG_INFO ( 1 , status )
ZEND_ARG_INFO ( 0 , options )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_signal , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , signo )
ZEND_ARG_INFO ( 0 , handler )
ZEND_ARG_INFO ( 0 , restart_syscalls )
ZEND_END_ARG_INFO ( )
2008-07-30 00:59:10 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_sigprocmask , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , how )
ZEND_ARG_INFO ( 0 , set )
2008-11-10 13:57:18 +08:00
ZEND_ARG_INFO ( 1 , oldset )
2008-07-30 00:59:10 +08:00
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_sigwaitinfo , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , set )
ZEND_ARG_INFO ( 1 , info )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_sigtimedwait , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , set )
ZEND_ARG_INFO ( 1 , info )
ZEND_ARG_INFO ( 0 , seconds )
ZEND_ARG_INFO ( 0 , nanoseconds )
ZEND_END_ARG_INFO ( )
2008-06-30 21:15:03 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_wifexited , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , status )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_wifstopped , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , status )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_wifsignaled , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , status )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_wifexitstatus , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , status )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_wtermsig , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , status )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_wstopsig , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , status )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_exec , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , path )
ZEND_ARG_INFO ( 0 , args )
ZEND_ARG_INFO ( 0 , envs )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_alarm , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , seconds )
ZEND_END_ARG_INFO ( )
# ifdef HAVE_GETPRIORITY
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_getpriority , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , pid )
ZEND_ARG_INFO ( 0 , process_identifier )
ZEND_END_ARG_INFO ( )
# endif
# ifdef HAVE_SETPRIORITY
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_setpriority , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , priority )
ZEND_ARG_INFO ( 0 , pid )
ZEND_ARG_INFO ( 0 , process_identifier )
ZEND_END_ARG_INFO ( )
# endif
2010-11-02 04:22:23 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_strerror , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , errno )
ZEND_END_ARG_INFO ( )
2008-06-30 21:15:03 +08:00
/* }}} */
2007-09-28 02:00:48 +08:00
const zend_function_entry pcntl_functions [ ] = {
2008-06-30 21:15:03 +08:00
PHP_FE ( pcntl_fork , arginfo_pcntl_void )
PHP_FE ( pcntl_waitpid , arginfo_pcntl_waitpid )
PHP_FE ( pcntl_wait , arginfo_pcntl_wait )
PHP_FE ( pcntl_signal , arginfo_pcntl_signal )
2008-07-30 00:46:11 +08:00
PHP_FE ( pcntl_signal_dispatch , arginfo_pcntl_void )
2008-06-30 21:15:03 +08:00
PHP_FE ( pcntl_wifexited , arginfo_pcntl_wifexited )
PHP_FE ( pcntl_wifstopped , arginfo_pcntl_wifstopped )
PHP_FE ( pcntl_wifsignaled , arginfo_pcntl_wifsignaled )
PHP_FE ( pcntl_wexitstatus , arginfo_pcntl_wifexitstatus )
PHP_FE ( pcntl_wtermsig , arginfo_pcntl_wtermsig )
PHP_FE ( pcntl_wstopsig , arginfo_pcntl_wstopsig )
PHP_FE ( pcntl_exec , arginfo_pcntl_exec )
PHP_FE ( pcntl_alarm , arginfo_pcntl_alarm )
2010-11-02 04:22:23 +08:00
PHP_FE ( pcntl_get_last_error , arginfo_pcntl_void )
PHP_FALIAS ( pcntl_errno , pcntl_get_last_error , NULL )
PHP_FE ( pcntl_strerror , arginfo_pcntl_strerror )
2004-08-28 20:20:06 +08:00
# ifdef HAVE_GETPRIORITY
2008-06-30 21:15:03 +08:00
PHP_FE ( pcntl_getpriority , arginfo_pcntl_getpriority )
2004-08-28 20:20:06 +08:00
# endif
# ifdef HAVE_SETPRIORITY
2008-06-30 21:15:03 +08:00
PHP_FE ( pcntl_setpriority , arginfo_pcntl_setpriority )
2008-07-30 00:59:10 +08:00
# endif
# ifdef HAVE_SIGPROCMASK
PHP_FE ( pcntl_sigprocmask , arginfo_pcntl_sigprocmask )
# endif
# if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
PHP_FE ( pcntl_sigwaitinfo , arginfo_pcntl_sigwaitinfo )
PHP_FE ( pcntl_sigtimedwait , arginfo_pcntl_sigtimedwait )
2004-08-28 20:20:06 +08:00
# endif
2011-07-25 19:42:53 +08:00
PHP_FE_END
2001-06-12 16:54:25 +08:00
} ;
zend_module_entry pcntl_module_entry = {
2001-10-12 07:33:59 +08:00
STANDARD_MODULE_HEADER ,
" pcntl " ,
pcntl_functions ,
2001-06-12 16:54:25 +08:00
PHP_MINIT ( pcntl ) ,
PHP_MSHUTDOWN ( pcntl ) ,
2002-08-22 12:20:10 +08:00
PHP_RINIT ( pcntl ) ,
PHP_RSHUTDOWN ( pcntl ) ,
2001-06-12 16:54:25 +08:00
PHP_MINFO ( pcntl ) ,
2001-10-12 07:33:59 +08:00
NO_VERSION_YET ,
2006-06-16 02:33:09 +08:00
PHP_MODULE_GLOBALS ( pcntl ) ,
PHP_GINIT ( pcntl ) ,
NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
2001-06-12 16:54:25 +08:00
} ;
# ifdef COMPILE_DL_PCNTL
ZEND_GET_MODULE ( pcntl )
# endif
2003-05-30 07:39:41 +08:00
static void pcntl_signal_handler ( int ) ;
2008-07-30 00:46:11 +08:00
static void pcntl_signal_dispatch ( ) ;
2001-06-20 05:42:57 +08:00
2001-06-12 16:54:25 +08:00
void php_register_signal_constants ( INIT_FUNC_ARGS )
{
2002-03-17 06:31:57 +08:00
2001-07-06 13:48:52 +08:00
/* Wait Constants */
# ifdef WNOHANG
REGISTER_LONG_CONSTANT ( " WNOHANG " , ( long ) WNOHANG , CONST_CS | CONST_PERSISTENT ) ;
# endif
# ifdef WUNTRACED
REGISTER_LONG_CONSTANT ( " WUNTRACED " , ( long ) WUNTRACED , CONST_CS | CONST_PERSISTENT ) ;
# endif
/* Signal Constants */
2001-06-13 09:13:05 +08:00
REGISTER_LONG_CONSTANT ( " SIG_IGN " , ( long ) SIG_IGN , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIG_DFL " , ( long ) SIG_DFL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIG_ERR " , ( long ) SIG_ERR , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGHUP " , ( long ) SIGHUP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGINT " , ( long ) SIGINT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGQUIT " , ( long ) SIGQUIT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGILL " , ( long ) SIGILL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTRAP " , ( long ) SIGTRAP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGABRT " , ( long ) SIGABRT , CONST_CS | CONST_PERSISTENT ) ;
2002-12-12 20:23:32 +08:00
# ifdef SIGIOT
2002-03-17 06:31:57 +08:00
REGISTER_LONG_CONSTANT ( " SIGIOT " , ( long ) SIGIOT , CONST_CS | CONST_PERSISTENT ) ;
2002-12-12 20:23:32 +08:00
# endif
2002-03-17 06:31:57 +08:00
REGISTER_LONG_CONSTANT ( " SIGBUS " , ( long ) SIGBUS , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGFPE " , ( long ) SIGFPE , CONST_CS | CONST_PERSISTENT ) ;
2001-06-13 09:13:05 +08:00
REGISTER_LONG_CONSTANT ( " SIGKILL " , ( long ) SIGKILL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGUSR1 " , ( long ) SIGUSR1 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGSEGV " , ( long ) SIGSEGV , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGUSR2 " , ( long ) SIGUSR2 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGPIPE " , ( long ) SIGPIPE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGALRM " , ( long ) SIGALRM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTERM " , ( long ) SIGTERM , CONST_CS | CONST_PERSISTENT ) ;
# ifdef SIGSTKFLT
REGISTER_LONG_CONSTANT ( " SIGSTKFLT " , ( long ) SIGSTKFLT , CONST_CS | CONST_PERSISTENT ) ;
# endif
# ifdef SIGCLD
REGISTER_LONG_CONSTANT ( " SIGCLD " , ( long ) SIGCLD , CONST_CS | CONST_PERSISTENT ) ;
# endif
# ifdef SIGCHLD
REGISTER_LONG_CONSTANT ( " SIGCHLD " , ( long ) SIGCHLD , CONST_CS | CONST_PERSISTENT ) ;
# endif
REGISTER_LONG_CONSTANT ( " SIGCONT " , ( long ) SIGCONT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGSTOP " , ( long ) SIGSTOP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTSTP " , ( long ) SIGTSTP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTTIN " , ( long ) SIGTTIN , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTTOU " , ( long ) SIGTTOU , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGURG " , ( long ) SIGURG , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGXCPU " , ( long ) SIGXCPU , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGXFSZ " , ( long ) SIGXFSZ , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGVTALRM " , ( long ) SIGVTALRM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGPROF " , ( long ) SIGPROF , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGWINCH " , ( long ) SIGWINCH , CONST_CS | CONST_PERSISTENT ) ;
2001-06-26 12:54:47 +08:00
# ifdef SIGPOLL
2001-06-13 09:13:05 +08:00
REGISTER_LONG_CONSTANT ( " SIGPOLL " , ( long ) SIGPOLL , CONST_CS | CONST_PERSISTENT ) ;
2001-06-26 12:54:47 +08:00
# endif
2001-06-13 09:13:05 +08:00
REGISTER_LONG_CONSTANT ( " SIGIO " , ( long ) SIGIO , CONST_CS | CONST_PERSISTENT ) ;
2001-06-26 12:54:47 +08:00
# ifdef SIGPWR
2001-06-13 09:13:05 +08:00
REGISTER_LONG_CONSTANT ( " SIGPWR " , ( long ) SIGPWR , CONST_CS | CONST_PERSISTENT ) ;
2001-06-26 12:54:47 +08:00
# endif
2004-12-14 22:01:06 +08:00
# ifdef SIGSYS
2001-06-13 09:13:05 +08:00
REGISTER_LONG_CONSTANT ( " SIGSYS " , ( long ) SIGSYS , CONST_CS | CONST_PERSISTENT ) ;
2001-11-09 04:23:33 +08:00
REGISTER_LONG_CONSTANT ( " SIGBABY " , ( long ) SIGSYS , CONST_CS | CONST_PERSISTENT ) ;
2004-12-14 22:01:06 +08:00
# endif
2003-02-18 09:41:06 +08:00
# if HAVE_GETPRIORITY || HAVE_SETPRIORITY
REGISTER_LONG_CONSTANT ( " PRIO_PGRP " , PRIO_PGRP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PRIO_USER " , PRIO_USER , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PRIO_PROCESS " , PRIO_PROCESS , CONST_CS | CONST_PERSISTENT ) ;
# endif
2008-07-30 00:59:10 +08:00
/* {{{ "how" argument for sigprocmask */
# ifdef HAVE_SIGPROCMASK
REGISTER_LONG_CONSTANT ( " SIG_BLOCK " , SIG_BLOCK , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 06:52:30 +08:00
REGISTER_LONG_CONSTANT ( " SIG_UNBLOCK " , SIG_UNBLOCK , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIG_SETMASK " , SIG_SETMASK , CONST_CS | CONST_PERSISTENT ) ;
2008-07-30 00:59:10 +08:00
# endif
/* }}} */
/* {{{ si_code */
# if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
REGISTER_LONG_CONSTANT ( " SI_USER " , SI_USER , CONST_CS | CONST_PERSISTENT ) ;
# ifdef SI_NOINFO
REGISTER_LONG_CONSTANT ( " SI_NOINFO " , SI_NOINFO , CONST_CS | CONST_PERSISTENT ) ;
# endif
# ifdef SI_KERNEL
REGISTER_LONG_CONSTANT ( " SI_KERNEL " , SI_KERNEL , CONST_CS | CONST_PERSISTENT ) ;
# endif
REGISTER_LONG_CONSTANT ( " SI_QUEUE " , SI_QUEUE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SI_TIMER " , SI_TIMER , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SI_MESGQ " , SI_MESGQ , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SI_ASYNCIO " , SI_ASYNCIO , CONST_CS | CONST_PERSISTENT ) ;
# ifdef SI_SIGIO
REGISTER_LONG_CONSTANT ( " SI_SIGIO " , SI_SIGIO , CONST_CS | CONST_PERSISTENT ) ;
# endif
# ifdef SI_TKILL
REGISTER_LONG_CONSTANT ( " SI_TKILL " , SI_TKILL , CONST_CS | CONST_PERSISTENT ) ;
# endif
/* si_code for SIGCHILD */
2009-03-26 07:34:08 +08:00
# ifdef CLD_EXITED
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " CLD_EXITED " , CLD_EXITED , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef CLD_KILLED
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " CLD_KILLED " , CLD_KILLED , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef CLD_DUMPED
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " CLD_DUMPED " , CLD_DUMPED , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef CLD_TRAPPED
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " CLD_TRAPPED " , CLD_TRAPPED , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef CLD_STOPPED
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " CLD_STOPPED " , CLD_STOPPED , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef CLD_CONTINUED
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " CLD_CONTINUED " , CLD_CONTINUED , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
2008-07-30 00:59:10 +08:00
/* si_code for SIGTRAP */
2009-03-26 07:34:08 +08:00
# ifdef TRAP_BRKPT
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " TRAP_BRKPT " , TRAP_BRKPT , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef TRAP_TRACE
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " TRAP_TRACE " , TRAP_TRACE , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
2008-07-30 00:59:10 +08:00
/* si_code for SIGPOLL */
2009-03-26 07:34:08 +08:00
# ifdef POLL_IN
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " POLL_IN " , POLL_IN , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef POLL_OUT
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " POLL_OUT " , POLL_OUT , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef POLL_MSG
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " POLL_MSG " , POLL_MSG , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef POLL_ERR
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " POLL_ERR " , POLL_ERR , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef POLL_PRI
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " POLL_PRI " , POLL_PRI , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef POLL_HUP
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " POLL_HUP " , POLL_HUP , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
2008-07-30 00:59:10 +08:00
2009-03-26 07:34:08 +08:00
# ifdef ILL_ILLOPC
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " ILL_ILLOPC " , ILL_ILLOPC , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef ILL_ILLOPN
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " ILL_ILLOPN " , ILL_ILLOPN , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef ILL_ILLADR
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " ILL_ILLADR " , ILL_ILLADR , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef ILL_ILLTRP
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " ILL_ILLTRP " , ILL_ILLTRP , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef ILL_PRVOPC
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " ILL_PRVOPC " , ILL_PRVOPC , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef ILL_PRVREG
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " ILL_PRVREG " , ILL_PRVREG , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef ILL_COPROC
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " ILL_COPROC " , ILL_COPROC , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef ILL_BADSTK
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " ILL_BADSTK " , ILL_BADSTK , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
2008-07-30 00:59:10 +08:00
2009-03-26 07:34:08 +08:00
# ifdef FPE_INTDIV
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " FPE_INTDIV " , FPE_INTDIV , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef FPE_INTOVF
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " FPE_INTOVF " , FPE_INTOVF , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef FPE_FLTDIV
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " FPE_FLTDIV " , FPE_FLTDIV , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef FPE_FLTOVF
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " FPE_FLTOVF " , FPE_FLTOVF , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef FPE_FLTUND
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " FPE_FLTUND " , FPE_FLTINV , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef FPE_FLTRES
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " FPE_FLTRES " , FPE_FLTRES , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef FPE_FLTINV
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " FPE_FLTINV " , FPE_FLTINV , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef FPE_FLTSUB
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " FPE_FLTSUB " , FPE_FLTSUB , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
2008-07-30 00:59:10 +08:00
2009-03-26 07:34:08 +08:00
# ifdef SEGV_MAPERR
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " SEGV_MAPERR " , SEGV_MAPERR , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef SEGV_ACCERR
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " SEGV_ACCERR " , SEGV_ACCERR , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
2008-07-30 00:59:10 +08:00
2009-03-26 07:34:08 +08:00
# ifdef BUS_ADRALN
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " BUS_ADRALN " , BUS_ADRALN , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef BUS_ADRERR
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " BUS_ADRERR " , BUS_ADRERR , CONST_CS | CONST_PERSISTENT ) ;
2009-03-26 07:34:08 +08:00
# endif
# ifdef BUS_OBJERR
2008-07-30 00:59:10 +08:00
REGISTER_LONG_CONSTANT ( " BUS_OBJERR " , BUS_OBJERR , CONST_CS | CONST_PERSISTENT ) ;
# endif
2009-03-26 07:34:08 +08:00
# endif /* HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT */
2008-07-30 00:59:10 +08:00
/* }}} */
2001-06-12 16:54:25 +08:00
}
2001-06-20 05:42:57 +08:00
2010-11-02 04:22:23 +08:00
static void php_pcntl_register_errno_constants ( INIT_FUNC_ARGS )
{
# ifdef EINTR
REGISTER_PCNTL_ERRNO_CONSTANT ( EINTR ) ;
# endif
# ifdef ECHILD
REGISTER_PCNTL_ERRNO_CONSTANT ( ECHILD ) ;
# endif
# ifdef EINVAL
REGISTER_PCNTL_ERRNO_CONSTANT ( EINVAL ) ;
# endif
# ifdef EAGAIN
REGISTER_PCNTL_ERRNO_CONSTANT ( EAGAIN ) ;
# endif
# ifdef ESRCH
REGISTER_PCNTL_ERRNO_CONSTANT ( ESRCH ) ;
# endif
# ifdef EACCES
REGISTER_PCNTL_ERRNO_CONSTANT ( EACCES ) ;
# endif
# ifdef EPERM
REGISTER_PCNTL_ERRNO_CONSTANT ( EPERM ) ;
# endif
# ifdef ENOMEM
REGISTER_PCNTL_ERRNO_CONSTANT ( ENOMEM ) ;
# endif
# ifdef E2BIG
REGISTER_PCNTL_ERRNO_CONSTANT ( E2BIG ) ;
# endif
# ifdef EFAULT
REGISTER_PCNTL_ERRNO_CONSTANT ( EFAULT ) ;
# endif
# ifdef EIO
REGISTER_PCNTL_ERRNO_CONSTANT ( EIO ) ;
# endif
# ifdef EISDIR
REGISTER_PCNTL_ERRNO_CONSTANT ( EISDIR ) ;
# endif
# ifdef ELIBBAD
REGISTER_PCNTL_ERRNO_CONSTANT ( ELIBBAD ) ;
# endif
# ifdef ELOOP
REGISTER_PCNTL_ERRNO_CONSTANT ( ELOOP ) ;
# endif
# ifdef EMFILE
REGISTER_PCNTL_ERRNO_CONSTANT ( EMFILE ) ;
# endif
# ifdef ENAMETOOLONG
REGISTER_PCNTL_ERRNO_CONSTANT ( ENAMETOOLONG ) ;
# endif
# ifdef ENFILE
REGISTER_PCNTL_ERRNO_CONSTANT ( ENFILE ) ;
# endif
# ifdef ENOENT
REGISTER_PCNTL_ERRNO_CONSTANT ( ENOENT ) ;
# endif
# ifdef ENOEXEC
REGISTER_PCNTL_ERRNO_CONSTANT ( ENOEXEC ) ;
# endif
# ifdef ENOTDIR
REGISTER_PCNTL_ERRNO_CONSTANT ( ENOTDIR ) ;
# endif
# ifdef ETXTBSY
REGISTER_PCNTL_ERRNO_CONSTANT ( ETXTBSY ) ;
# endif
}
2006-06-16 02:33:09 +08:00
static PHP_GINIT_FUNCTION ( pcntl )
2002-08-22 12:20:10 +08:00
{
2005-05-07 22:58:12 +08:00
memset ( pcntl_globals , 0 , sizeof ( * pcntl_globals ) ) ;
2001-07-31 03:40:29 +08:00
}
2002-08-22 12:20:10 +08:00
PHP_RINIT_FUNCTION ( pcntl )
2001-07-31 03:40:29 +08:00
{
2005-05-07 22:58:12 +08:00
zend_hash_init ( & PCNTL_G ( php_signal_table ) , 16 , NULL , ZVAL_PTR_DTOR , 0 ) ;
PCNTL_G ( head ) = PCNTL_G ( tail ) = PCNTL_G ( spares ) = NULL ;
2002-08-22 12:20:10 +08:00
return SUCCESS ;
2001-07-31 03:40:29 +08:00
}
PHP_MINIT_FUNCTION ( pcntl )
{
2002-03-17 06:31:57 +08:00
php_register_signal_constants ( INIT_FUNC_ARGS_PASSTHRU ) ;
2010-11-02 04:22:23 +08:00
php_pcntl_register_errno_constants ( INIT_FUNC_ARGS_PASSTHRU ) ;
2008-07-30 00:46:11 +08:00
php_add_tick_function ( pcntl_signal_dispatch ) ;
2002-08-22 12:20:10 +08:00
2001-06-12 16:54:25 +08:00
return SUCCESS ;
}
2001-07-31 03:40:29 +08:00
2001-06-12 16:54:25 +08:00
PHP_MSHUTDOWN_FUNCTION ( pcntl )
{
return SUCCESS ;
}
2002-08-22 12:20:10 +08:00
PHP_RSHUTDOWN_FUNCTION ( pcntl )
{
2005-05-07 22:58:12 +08:00
struct php_pcntl_pending_signal * sig ;
/* FIXME: if a signal is delivered after this point, things will go pear shaped;
* need to remove signal handlers */
2002-08-22 12:20:10 +08:00
zend_hash_destroy ( & PCNTL_G ( php_signal_table ) ) ;
2005-05-07 22:58:12 +08:00
while ( PCNTL_G ( head ) ) {
sig = PCNTL_G ( head ) ;
PCNTL_G ( head ) = sig - > next ;
efree ( sig ) ;
}
while ( PCNTL_G ( spares ) ) {
sig = PCNTL_G ( spares ) ;
PCNTL_G ( spares ) = sig - > next ;
efree ( sig ) ;
}
2002-08-22 12:20:10 +08:00
return SUCCESS ;
}
2001-07-31 03:40:29 +08:00
2001-06-12 16:54:25 +08:00
PHP_MINFO_FUNCTION ( pcntl )
{
php_info_print_table_start ( ) ;
php_info_print_table_header ( 2 , " pcntl support " , " enabled " ) ;
php_info_print_table_end ( ) ;
}
2001-07-06 13:48:52 +08:00
2001-11-09 06:11:41 +08:00
/* {{{ proto int pcntl_fork(void)
2001-06-12 16:54:25 +08:00
Forks the currently running process following the same behavior as the UNIX fork ( ) system call */
PHP_FUNCTION ( pcntl_fork )
{
pid_t id ;
2002-03-17 06:31:57 +08:00
id = fork ( ) ;
2001-06-12 16:54:25 +08:00
if ( id = = - 1 ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2007-11-28 01:13:18 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error %d " , errno ) ;
2001-06-12 16:54:25 +08:00
}
RETURN_LONG ( ( long ) id ) ;
}
/* }}} */
2002-06-04 23:51:25 +08:00
/* {{{ proto int pcntl_alarm(int seconds)
Set an alarm clock for delivery of a signal */
PHP_FUNCTION ( pcntl_alarm )
{
long seconds ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & seconds ) = = FAILURE )
return ;
RETURN_LONG ( ( long ) alarm ( seconds ) ) ;
}
/* }}} */
2003-06-22 22:33:09 +08:00
/* {{{ proto int pcntl_waitpid(int pid, int &status, int options)
2001-11-09 06:11:41 +08:00
Waits on or returns the status of a forked child as defined by the waitpid ( ) system call */
2001-06-12 16:54:25 +08:00
PHP_FUNCTION ( pcntl_waitpid )
{
2002-04-24 05:21:41 +08:00
long pid , options = 0 ;
zval * z_status = NULL ;
int status ;
pid_t child_id ;
2001-06-12 16:54:25 +08:00
2002-04-24 05:21:41 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " lz|l " , & pid , & z_status , & options ) = = FAILURE )
return ;
2002-05-07 07:01:46 +08:00
convert_to_long_ex ( & z_status ) ;
2001-06-12 16:54:25 +08:00
2002-04-24 05:21:41 +08:00
status = Z_LVAL_P ( z_status ) ;
2001-06-12 16:54:25 +08:00
2002-04-24 05:21:41 +08:00
child_id = waitpid ( ( pid_t ) pid , & status , options ) ;
2010-11-02 04:22:23 +08:00
if ( child_id < 0 ) {
PCNTL_G ( last_error ) = errno ;
}
2002-04-24 05:21:41 +08:00
Z_LVAL_P ( z_status ) = status ;
RETURN_LONG ( ( long ) child_id ) ;
2001-06-12 16:54:25 +08:00
}
/* }}} */
2003-10-29 01:08:18 +08:00
/* {{{ proto int pcntl_wait(int &status)
Waits on or returns the status of a forked child as defined by the waitpid ( ) system call */
PHP_FUNCTION ( pcntl_wait )
{
2003-11-06 07:44:09 +08:00
long options = 0 ;
2003-10-29 01:08:18 +08:00
zval * z_status = NULL ;
int status ;
pid_t child_id ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z|l " , & z_status , & options ) = = FAILURE )
return ;
convert_to_long_ex ( & z_status ) ;
status = Z_LVAL_P ( z_status ) ;
# ifdef HAVE_WAIT3
if ( options ) {
child_id = wait3 ( & status , options , NULL ) ;
}
else {
child_id = wait ( & status ) ;
}
# else
child_id = wait ( & status ) ;
# endif
2010-11-02 04:22:23 +08:00
if ( child_id < 0 ) {
PCNTL_G ( last_error ) = errno ;
}
2003-10-29 01:08:18 +08:00
Z_LVAL_P ( z_status ) = status ;
RETURN_LONG ( ( long ) child_id ) ;
}
/* }}} */
2003-06-22 22:33:09 +08:00
/* {{{ proto bool pcntl_wifexited(int status)
2001-07-06 13:48:52 +08:00
Returns true if the child status code represents a successful exit */
PHP_FUNCTION ( pcntl_wifexited )
{
# ifdef WIFEXITED
2008-06-22 23:16:11 +08:00
long status_word ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & status_word ) = = FAILURE ) {
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
if ( WIFEXITED ( status_word ) )
RETURN_TRUE ;
2001-07-06 13:48:52 +08:00
# endif
RETURN_FALSE ;
}
/* }}} */
2003-06-22 22:33:09 +08:00
/* {{{ proto bool pcntl_wifstopped(int status)
2001-11-09 06:11:41 +08:00
Returns true if the child status code represents a stopped process ( WUNTRACED must have been used with waitpid ) */
2001-07-06 13:48:52 +08:00
PHP_FUNCTION ( pcntl_wifstopped )
{
# ifdef WIFSTOPPED
2008-06-22 23:16:11 +08:00
long status_word ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & status_word ) = = FAILURE ) {
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
if ( WIFSTOPPED ( status_word ) )
RETURN_TRUE ;
2001-07-06 13:48:52 +08:00
# endif
RETURN_FALSE ;
}
/* }}} */
2003-06-22 22:33:09 +08:00
/* {{{ proto bool pcntl_wifsignaled(int status)
2001-07-06 13:48:52 +08:00
Returns true if the child status code represents a process that was terminated due to a signal */
PHP_FUNCTION ( pcntl_wifsignaled )
{
# ifdef WIFSIGNALED
2008-06-22 23:16:11 +08:00
long status_word ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & status_word ) = = FAILURE ) {
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
if ( WIFSIGNALED ( status_word ) )
RETURN_TRUE ;
2001-07-06 13:48:52 +08:00
# endif
RETURN_FALSE ;
}
/* }}} */
2003-06-22 22:33:09 +08:00
/* {{{ proto int pcntl_wexitstatus(int status)
2001-07-06 13:48:52 +08:00
Returns the status code of a child ' s exit */
PHP_FUNCTION ( pcntl_wexitstatus )
{
# ifdef WEXITSTATUS
2008-06-22 23:16:11 +08:00
long status_word ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & status_word ) = = FAILURE ) {
return ;
2001-07-06 13:48:52 +08:00
}
2009-05-26 22:01:39 +08:00
RETURN_LONG ( WEXITSTATUS ( status_word ) ) ;
2001-07-06 13:48:52 +08:00
# else
RETURN_FALSE ;
# endif
}
/* }}} */
2003-06-22 22:33:09 +08:00
/* {{{ proto int pcntl_wtermsig(int status)
2001-07-06 13:48:52 +08:00
Returns the number of the signal that terminated the process who ' s status code is passed */
PHP_FUNCTION ( pcntl_wtermsig )
{
# ifdef WTERMSIG
2008-06-22 23:16:11 +08:00
long status_word ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & status_word ) = = FAILURE ) {
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
2002-03-17 06:31:57 +08:00
RETURN_LONG ( WTERMSIG ( status_word ) ) ;
2001-07-06 13:48:52 +08:00
# else
RETURN_FALSE ;
# endif
}
/* }}} */
2003-06-22 22:33:09 +08:00
/* {{{ proto int pcntl_wstopsig(int status)
2001-11-09 06:11:41 +08:00
Returns the number of the signal that caused the process to stop who ' s status code is passed */
2001-07-06 13:48:52 +08:00
PHP_FUNCTION ( pcntl_wstopsig )
{
# ifdef WSTOPSIG
2008-06-22 23:16:11 +08:00
long status_word ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & status_word ) = = FAILURE ) {
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
RETURN_LONG ( WSTOPSIG ( status_word ) ) ;
2001-07-06 13:48:52 +08:00
# else
RETURN_FALSE ;
# endif
}
/* }}} */
2002-01-04 22:08:25 +08:00
/* {{{ proto bool pcntl_exec(string path [, array args [, array envs]])
2001-11-09 06:11:41 +08:00
Executes specified program in current process space as defined by exec ( 2 ) */
2001-09-30 14:59:12 +08:00
PHP_FUNCTION ( pcntl_exec )
{
2008-09-13 03:49:18 +08:00
zval * args = NULL , * envs = NULL ;
2001-09-30 14:59:12 +08:00
zval * * element ;
HashTable * args_hash , * envs_hash ;
2002-03-17 06:31:57 +08:00
int argc = 0 , argi = 0 ;
int envc = 0 , envi = 0 ;
int return_val = 0 ;
char * * argv = NULL , * * envp = NULL ;
char * * current_arg , * * pair ;
2001-09-30 14:59:12 +08:00
int pair_length ;
2002-03-17 06:31:57 +08:00
char * key ;
2008-06-22 23:16:11 +08:00
uint key_length ;
2001-09-30 14:59:12 +08:00
char * path ;
int path_len ;
2008-06-22 23:16:11 +08:00
ulong key_num ;
2002-03-17 06:31:57 +08:00
2002-03-17 06:19:10 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|aa " , & path , & path_len , & args , & envs ) = = FAILURE ) {
2001-09-30 14:59:12 +08:00
return ;
}
2002-03-17 06:31:57 +08:00
if ( ZEND_NUM_ARGS ( ) > 1 ) {
2012-03-29 15:44:19 +08:00
/* Build argumnent list */
2002-03-17 06:31:57 +08:00
args_hash = HASH_OF ( args ) ;
argc = zend_hash_num_elements ( args_hash ) ;
2004-06-30 09:12:06 +08:00
argv = safe_emalloc ( ( argc + 2 ) , sizeof ( char * ) , 0 ) ;
2002-03-17 06:31:57 +08:00
* argv = path ;
for ( zend_hash_internal_pointer_reset ( args_hash ) , current_arg = argv + 1 ;
( argi < argc & & ( zend_hash_get_current_data ( args_hash , ( void * * ) & element ) = = SUCCESS ) ) ;
( argi + + , current_arg + + , zend_hash_move_forward ( args_hash ) ) ) {
2002-05-07 03:48:39 +08:00
convert_to_string_ex ( element ) ;
2002-03-17 06:31:57 +08:00
* current_arg = Z_STRVAL_PP ( element ) ;
2001-09-30 14:59:12 +08:00
}
2002-03-17 06:31:57 +08:00
* ( current_arg ) = NULL ;
2001-09-30 14:59:12 +08:00
} else {
2004-06-30 09:12:06 +08:00
argv = emalloc ( 2 * sizeof ( char * ) ) ;
2002-03-17 06:31:57 +08:00
* argv = path ;
* ( argv + 1 ) = NULL ;
2001-09-30 14:59:12 +08:00
}
2002-03-17 06:31:57 +08:00
if ( ZEND_NUM_ARGS ( ) = = 3 ) {
2001-09-30 14:59:12 +08:00
/* Build environment pair list */
2002-03-17 06:31:57 +08:00
envs_hash = HASH_OF ( envs ) ;
envc = zend_hash_num_elements ( envs_hash ) ;
2004-06-30 09:12:06 +08:00
envp = safe_emalloc ( ( envc + 1 ) , sizeof ( char * ) , 0 ) ;
2002-03-17 06:31:57 +08:00
for ( zend_hash_internal_pointer_reset ( envs_hash ) , pair = envp ;
( envi < envc & & ( zend_hash_get_current_data ( envs_hash , ( void * * ) & element ) = = SUCCESS ) ) ;
( envi + + , pair + + , zend_hash_move_forward ( envs_hash ) ) ) {
switch ( return_val = zend_hash_get_current_key_ex ( envs_hash , & key , & key_length , & key_num , 0 , NULL ) ) {
2001-09-30 14:59:12 +08:00
case HASH_KEY_IS_LONG :
2004-06-30 09:12:06 +08:00
key = emalloc ( 101 ) ;
2001-09-30 14:59:12 +08:00
snprintf ( key , 100 , " %ld " , key_num ) ;
2002-03-17 06:31:57 +08:00
key_length = strlen ( key ) ;
break ;
2001-09-30 14:59:12 +08:00
case HASH_KEY_NON_EXISTANT :
pair - - ;
continue ;
}
2002-05-07 03:48:39 +08:00
convert_to_string_ex ( element ) ;
2001-09-30 14:59:12 +08:00
/* Length of element + equal sign + length of key + null */
2002-03-17 06:31:57 +08:00
pair_length = Z_STRLEN_PP ( element ) + key_length + 2 ;
* pair = emalloc ( pair_length ) ;
strlcpy ( * pair , key , key_length ) ;
2001-09-30 14:59:12 +08:00
strlcat ( * pair , " = " , pair_length ) ;
strlcat ( * pair , Z_STRVAL_PP ( element ) , pair_length ) ;
2002-03-17 06:31:57 +08:00
2001-09-30 14:59:12 +08:00
/* Cleanup */
2004-06-30 09:12:06 +08:00
if ( return_val = = HASH_KEY_IS_LONG ) efree ( key ) ;
2001-09-30 14:59:12 +08:00
}
2002-03-17 06:31:57 +08:00
* ( pair ) = NULL ;
2009-09-30 21:04:28 +08:00
if ( execve ( path , argv , envp ) = = - 1 ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2009-09-30 21:04:28 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error has occured: (errno %d) %s " , errno , strerror ( errno ) ) ;
}
2002-03-17 06:31:57 +08:00
2009-09-30 21:04:28 +08:00
/* Cleanup */
2002-05-07 03:48:39 +08:00
for ( pair = envp ; * pair ! = NULL ; pair + + ) efree ( * pair ) ;
2004-06-30 09:12:06 +08:00
efree ( envp ) ;
2009-09-30 21:04:28 +08:00
} else {
if ( execv ( path , argv ) = = - 1 ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2009-09-30 21:04:28 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error has occured: (errno %d) %s " , errno , strerror ( errno ) ) ;
}
2002-05-07 03:48:39 +08:00
}
2004-06-30 09:12:06 +08:00
efree ( argv ) ;
2002-03-17 06:31:57 +08:00
2001-09-30 14:59:12 +08:00
RETURN_FALSE ;
}
/* }}} */
2003-06-22 22:33:09 +08:00
/* {{{ proto bool pcntl_signal(int signo, callback handle [, bool restart_syscalls])
2001-11-09 06:11:41 +08:00
Assigns a system signal handler to a PHP function */
2001-06-12 16:54:25 +08:00
PHP_FUNCTION ( pcntl_signal )
{
2002-08-22 12:20:10 +08:00
zval * handle , * * dest_handle = NULL ;
2002-03-17 06:31:57 +08:00
char * func_name ;
2002-08-22 12:20:10 +08:00
long signo ;
zend_bool restart_syscalls = 1 ;
2001-06-12 16:54:25 +08:00
2002-08-22 12:20:10 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " lz|b " , & signo , & handle , & restart_syscalls ) = = FAILURE ) {
2009-03-28 11:12:52 +08:00
return ;
2001-06-12 16:54:25 +08:00
}
2005-05-07 22:58:12 +08:00
if ( ! PCNTL_G ( spares ) ) {
/* since calling malloc() from within a signal handler is not portable,
* pre - allocate a few records for recording signals */
int i ;
for ( i = 0 ; i < 32 ; i + + ) {
struct php_pcntl_pending_signal * psig ;
psig = emalloc ( sizeof ( * psig ) ) ;
psig - > next = PCNTL_G ( spares ) ;
PCNTL_G ( spares ) = psig ;
}
}
2001-06-12 16:54:25 +08:00
/* Special long value case for SIG_DFL and SIG_IGN */
2002-08-22 12:20:10 +08:00
if ( Z_TYPE_P ( handle ) = = IS_LONG ) {
if ( Z_LVAL_P ( handle ) ! = ( long ) SIG_DFL & & Z_LVAL_P ( handle ) ! = ( long ) SIG_IGN ) {
2006-08-31 23:42:18 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid value for handle argument specified " ) ;
2001-06-12 16:54:25 +08:00
}
2002-08-22 12:20:10 +08:00
if ( php_signal ( signo , ( Sigfunc * ) Z_LVAL_P ( handle ) , ( int ) restart_syscalls ) = = SIG_ERR ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2004-01-23 15:02:15 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error assigning signal " ) ;
2002-03-17 06:31:57 +08:00
RETURN_FALSE ;
2001-06-12 16:54:25 +08:00
}
RETURN_TRUE ;
2002-03-17 06:31:57 +08:00
}
2001-06-12 16:54:25 +08:00
2008-08-02 12:46:07 +08:00
if ( ! zend_is_callable ( handle , 0 , & func_name TSRMLS_CC ) ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = EINVAL ;
2002-12-12 21:08:59 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s is not a callable function name error " , func_name ) ;
2002-03-17 06:31:57 +08:00
efree ( func_name ) ;
2001-06-12 16:54:25 +08:00
RETURN_FALSE ;
}
2002-03-17 06:31:57 +08:00
efree ( func_name ) ;
2001-06-12 16:54:25 +08:00
2002-08-22 12:20:10 +08:00
/* Add the function name to our signal table */
zend_hash_index_update ( & PCNTL_G ( php_signal_table ) , signo , ( void * * ) & handle , sizeof ( zval * ) , ( void * * ) & dest_handle ) ;
if ( dest_handle ) zval_add_ref ( dest_handle ) ;
2010-11-02 06:43:59 +08:00
if ( php_signal4 ( signo , pcntl_signal_handler , ( int ) restart_syscalls , 1 ) = = SIG_ERR ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2004-01-23 15:02:15 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error assigning signal " ) ;
2002-08-22 12:20:10 +08:00
RETURN_FALSE ;
2001-06-12 16:54:25 +08:00
}
2002-03-17 06:31:57 +08:00
RETURN_TRUE ;
2001-06-12 16:54:25 +08:00
}
/* }}} */
2008-07-30 00:46:11 +08:00
/* {{{ proto bool pcntl_signal_dispatch()
Dispatch signals to signal handlers */
PHP_FUNCTION ( pcntl_signal_dispatch )
{
pcntl_signal_dispatch ( ) ;
RETURN_TRUE ;
}
/* }}} */
2008-07-30 00:59:10 +08:00
# ifdef HAVE_SIGPROCMASK
2008-11-10 13:57:18 +08:00
/* {{{ proto bool pcntl_sigprocmask(int how, array set[, array &oldset])
2008-07-30 00:59:10 +08:00
Examine and change blocked signals */
PHP_FUNCTION ( pcntl_sigprocmask )
{
long how , signo ;
2008-11-10 13:57:18 +08:00
zval * user_set , * user_oldset = NULL , * * user_signo ;
sigset_t set , oldset ;
2008-07-30 00:59:10 +08:00
HashPosition pos ;
2008-11-10 13:57:18 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " la|z " , & how , & user_set , & user_oldset ) = = FAILURE ) {
2008-07-30 00:59:10 +08:00
return ;
}
2008-11-10 13:57:18 +08:00
if ( sigemptyset ( & set ) ! = 0 | | sigemptyset ( & oldset ) ! = 0 ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2008-07-30 00:59:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , strerror ( errno ) ) ;
RETURN_FALSE ;
}
zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_P ( user_set ) , & pos ) ;
while ( zend_hash_get_current_data_ex ( Z_ARRVAL_P ( user_set ) , ( void * * ) & user_signo , & pos ) = = SUCCESS )
{
if ( Z_TYPE_PP ( user_signo ) ! = IS_LONG ) {
SEPARATE_ZVAL ( user_signo ) ;
convert_to_long_ex ( user_signo ) ;
}
signo = Z_LVAL_PP ( user_signo ) ;
if ( sigaddset ( & set , signo ) ! = 0 ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2008-07-30 00:59:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , strerror ( errno ) ) ;
RETURN_FALSE ;
}
zend_hash_move_forward_ex ( Z_ARRVAL_P ( user_set ) , & pos ) ;
}
2008-11-10 13:57:18 +08:00
if ( sigprocmask ( how , & set , & oldset ) ! = 0 ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2008-07-30 00:59:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , strerror ( errno ) ) ;
RETURN_FALSE ;
}
2008-11-10 13:57:18 +08:00
if ( user_oldset ! = NULL ) {
if ( Z_TYPE_P ( user_oldset ) ! = IS_ARRAY ) {
zval_dtor ( user_oldset ) ;
array_init ( user_oldset ) ;
} else {
zend_hash_clean ( Z_ARRVAL_P ( user_oldset ) ) ;
}
for ( signo = 1 ; signo < MAX ( NSIG - 1 , SIGRTMAX ) ; + + signo ) {
if ( sigismember ( & oldset , signo ) ! = 1 ) {
continue ;
}
add_next_index_long ( user_oldset , signo ) ;
}
}
2008-07-30 00:59:10 +08:00
RETURN_TRUE ;
}
/* }}} */
# endif
# if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
static void pcntl_sigwaitinfo ( INTERNAL_FUNCTION_PARAMETERS , int timedwait ) /* { { { */
{
zval * user_set , * * user_signo , * user_siginfo = NULL ;
long tv_sec = 0 , tv_nsec = 0 ;
sigset_t set ;
HashPosition pos ;
int signo ;
siginfo_t siginfo ;
struct timespec timeout ;
if ( timedwait ) {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " a|zll " , & user_set , & user_siginfo , & tv_sec , & tv_nsec ) = = FAILURE ) {
return ;
}
} else {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " a|z " , & user_set , & user_siginfo ) = = FAILURE ) {
return ;
}
}
if ( sigemptyset ( & set ) ! = 0 ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2008-07-30 00:59:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , strerror ( errno ) ) ;
RETURN_FALSE ;
}
zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_P ( user_set ) , & pos ) ;
while ( zend_hash_get_current_data_ex ( Z_ARRVAL_P ( user_set ) , ( void * * ) & user_signo , & pos ) = = SUCCESS )
{
if ( Z_TYPE_PP ( user_signo ) ! = IS_LONG ) {
SEPARATE_ZVAL ( user_signo ) ;
convert_to_long_ex ( user_signo ) ;
}
signo = Z_LVAL_PP ( user_signo ) ;
if ( sigaddset ( & set , signo ) ! = 0 ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2008-07-30 00:59:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , strerror ( errno ) ) ;
RETURN_FALSE ;
}
zend_hash_move_forward_ex ( Z_ARRVAL_P ( user_set ) , & pos ) ;
}
if ( timedwait ) {
timeout . tv_sec = ( time_t ) tv_sec ;
timeout . tv_nsec = tv_nsec ;
signo = sigtimedwait ( & set , & siginfo , & timeout ) ;
} else {
signo = sigwaitinfo ( & set , & siginfo ) ;
}
if ( signo = = - 1 & & errno ! = EAGAIN ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2008-07-30 00:59:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , strerror ( errno ) ) ;
}
2009-03-28 11:21:04 +08:00
/*
* sigtimedwait and sigwaitinfo can return 0 on success on some
* platforms , e . g . NetBSD
*/
if ( ! signo & & siginfo . si_signo ) {
signo = siginfo . si_signo ;
}
2008-07-30 00:59:10 +08:00
if ( signo > 0 & & user_siginfo ) {
if ( Z_TYPE_P ( user_siginfo ) ! = IS_ARRAY ) {
zval_dtor ( user_siginfo ) ;
array_init ( user_siginfo ) ;
2008-11-10 13:57:18 +08:00
} else {
zend_hash_clean ( Z_ARRVAL_P ( user_siginfo ) ) ;
2008-07-30 00:59:10 +08:00
}
add_assoc_long_ex ( user_siginfo , " signo " , sizeof ( " signo " ) , siginfo . si_signo ) ;
add_assoc_long_ex ( user_siginfo , " errno " , sizeof ( " errno " ) , siginfo . si_errno ) ;
add_assoc_long_ex ( user_siginfo , " code " , sizeof ( " code " ) , siginfo . si_code ) ;
switch ( signo ) {
# ifdef SIGCHLD
case SIGCHLD :
add_assoc_long_ex ( user_siginfo , " status " , sizeof ( " status " ) , siginfo . si_status ) ;
2008-08-05 23:12:19 +08:00
# ifdef si_utime
2008-07-30 00:59:10 +08:00
add_assoc_double_ex ( user_siginfo , " utime " , sizeof ( " utime " ) , siginfo . si_utime ) ;
2008-08-05 23:12:19 +08:00
# endif
# ifdef si_stime
2008-07-30 00:59:10 +08:00
add_assoc_double_ex ( user_siginfo , " stime " , sizeof ( " stime " ) , siginfo . si_stime ) ;
2008-08-05 23:12:19 +08:00
# endif
2008-07-30 00:59:10 +08:00
add_assoc_long_ex ( user_siginfo , " pid " , sizeof ( " pid " ) , siginfo . si_pid ) ;
add_assoc_long_ex ( user_siginfo , " uid " , sizeof ( " uid " ) , siginfo . si_uid ) ;
break ;
# endif
case SIGILL :
case SIGFPE :
case SIGSEGV :
case SIGBUS :
add_assoc_double_ex ( user_siginfo , " addr " , sizeof ( " addr " ) , ( long ) siginfo . si_addr ) ;
break ;
# ifdef SIGPOLL
case SIGPOLL :
add_assoc_long_ex ( user_siginfo , " band " , sizeof ( " band " ) , siginfo . si_band ) ;
2008-08-05 23:12:19 +08:00
# ifdef si_fd
2008-07-30 00:59:10 +08:00
add_assoc_long_ex ( user_siginfo , " fd " , sizeof ( " fd " ) , siginfo . si_fd ) ;
2008-08-05 23:12:19 +08:00
# endif
2008-07-30 00:59:10 +08:00
break ;
# endif
EMPTY_SWITCH_DEFAULT_CASE ( ) ;
}
}
RETURN_LONG ( signo ) ;
}
/* }}} */
2008-08-05 23:12:19 +08:00
/* {{{ proto int pcnlt_sigwaitinfo(array set[, array &siginfo])
2008-07-30 00:59:10 +08:00
Synchronously wait for queued signals */
PHP_FUNCTION ( pcntl_sigwaitinfo )
{
pcntl_sigwaitinfo ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
/* }}} */
2008-08-05 23:12:19 +08:00
/* {{{ proto int pcntl_sigtimedwait(array set[, array &siginfo[, int seconds[, int nanoseconds]]])
2008-07-30 00:59:10 +08:00
Wait for queued signals */
PHP_FUNCTION ( pcntl_sigtimedwait )
{
pcntl_sigwaitinfo ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
/* }}} */
# endif
2003-02-18 09:41:06 +08:00
# ifdef HAVE_GETPRIORITY
2003-06-22 22:33:09 +08:00
/* {{{ proto int pcntl_getpriority([int pid [, int process_identifier]])
2003-02-18 09:41:06 +08:00
Get the priority of any process */
PHP_FUNCTION ( pcntl_getpriority )
{
long who = PRIO_PROCESS ;
long pid = getpid ( ) ;
int pri ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |ll " , & pid , & who ) = = FAILURE ) {
RETURN_FALSE ;
}
/* needs to be cleared, since any returned value is valid */
errno = 0 ;
pri = getpriority ( who , pid ) ;
if ( errno ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2003-02-18 09:41:06 +08:00
switch ( errno ) {
case ESRCH :
2003-08-31 22:35:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error %d: No process was located using the given parameters " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
case EINVAL :
2003-08-31 22:35:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error %d: Invalid identifier flag " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
default :
2003-08-31 22:35:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unknown error %d has occured " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
}
RETURN_FALSE ;
}
RETURN_LONG ( pri ) ;
}
/* }}} */
# endif
# ifdef HAVE_SETPRIORITY
2003-06-22 22:33:09 +08:00
/* {{{ proto bool pcntl_setpriority(int priority [, int pid [, int process_identifier]])
2003-02-18 09:41:06 +08:00
Change the priority of any process */
PHP_FUNCTION ( pcntl_setpriority )
{
long who = PRIO_PROCESS ;
long pid = getpid ( ) ;
long pri ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l|ll " , & pri , & pid , & who ) = = FAILURE ) {
RETURN_FALSE ;
}
if ( setpriority ( who , pid , pri ) ) {
2010-11-02 04:22:23 +08:00
PCNTL_G ( last_error ) = errno ;
2003-02-18 09:41:06 +08:00
switch ( errno ) {
case ESRCH :
2003-08-31 22:35:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error %d: No process was located using the given parameters " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
case EINVAL :
2003-08-31 22:35:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error %d: Invalid identifier flag " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
case EPERM :
2003-08-31 22:35:10 +08:00
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 ) ;
2003-02-18 09:41:06 +08:00
break ;
case EACCES :
2003-08-31 22:35:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error %d: Only a super user may attempt to increase the process priority " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
default :
2003-08-31 22:35:10 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unknown error %d has occured " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
}
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
# endif
2010-11-02 04:22:23 +08:00
/* {{{ proto int pcntl_get_last_error(void)
Retrieve the error number set by the last pcntl function which failed . */
PHP_FUNCTION ( pcntl_get_last_error )
{
RETURN_LONG ( PCNTL_G ( last_error ) ) ;
}
/* }}} */
/* {{{ proto string pcntl_strerror(int errno)
Retrieve the system error message associated with the given errno . */
PHP_FUNCTION ( pcntl_strerror )
{
long error ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & error ) = = FAILURE ) {
RETURN_FALSE ;
}
RETURN_STRING ( strerror ( error ) , 1 ) ;
}
/* }}} */
2001-06-26 01:56:23 +08:00
/* Our custom signal handler that calls the appropriate php_function */
2001-06-20 05:42:57 +08:00
static void pcntl_signal_handler ( int signo )
{
2005-05-07 22:58:12 +08:00
struct php_pcntl_pending_signal * psig ;
2001-07-31 03:40:29 +08:00
TSRMLS_FETCH ( ) ;
2002-03-17 06:31:57 +08:00
2005-05-07 22:58:12 +08:00
psig = PCNTL_G ( spares ) ;
if ( ! psig ) {
/* oops, too many signals for us to track, so we'll forget about this one */
return ;
}
PCNTL_G ( spares ) = psig - > next ;
psig - > signo = signo ;
psig - > next = NULL ;
/* the head check is important, as the tick handler cannot atomically clear both
* the head and tail */
if ( PCNTL_G ( head ) & & PCNTL_G ( tail ) ) {
PCNTL_G ( tail ) - > next = psig ;
} else {
PCNTL_G ( head ) = psig ;
2001-06-20 05:42:57 +08:00
}
2005-05-07 22:58:12 +08:00
PCNTL_G ( tail ) = psig ;
2001-06-20 05:42:57 +08:00
}
2008-07-30 00:46:11 +08:00
void pcntl_signal_dispatch ( )
2001-07-30 16:24:42 +08:00
{
2002-08-22 12:20:10 +08:00
zval * param , * * handle , * retval ;
2005-05-07 22:58:12 +08:00
struct php_pcntl_pending_signal * queue , * next ;
2010-11-02 06:43:59 +08:00
sigset_t mask ;
sigset_t old_mask ;
2001-07-30 16:24:42 +08:00
TSRMLS_FETCH ( ) ;
2010-11-02 06:43:59 +08:00
/* Mask all signals */
sigfillset ( & mask ) ;
sigprocmask ( SIG_BLOCK , & mask , & old_mask ) ;
2001-06-20 05:42:57 +08:00
/* Bail if the queue is empty or if we are already playing the queue*/
2010-11-02 06:43:59 +08:00
if ( ! PCNTL_G ( head ) | | PCNTL_G ( processing_signal_queue ) ) {
sigprocmask ( SIG_SETMASK , & old_mask , NULL ) ;
2001-06-20 05:42:57 +08:00
return ;
2010-11-02 06:43:59 +08:00
}
2001-06-20 05:42:57 +08:00
2002-08-22 12:20:10 +08:00
/* Prevent reentrant handler calls */
2002-03-17 06:31:57 +08:00
PCNTL_G ( processing_signal_queue ) = 1 ;
2005-05-07 22:58:12 +08:00
queue = PCNTL_G ( head ) ;
PCNTL_G ( head ) = NULL ; /* simple stores are atomic */
2001-06-20 05:42:57 +08:00
/* Allocate */
2005-05-07 22:58:12 +08:00
while ( queue ) {
if ( zend_hash_index_find ( & PCNTL_G ( php_signal_table ) , queue - > signo , ( void * * ) & handle ) = = SUCCESS ) {
2006-05-31 01:40:52 +08:00
MAKE_STD_ZVAL ( retval ) ;
MAKE_STD_ZVAL ( param ) ;
ZVAL_NULL ( retval ) ;
2005-05-07 22:58:12 +08:00
ZVAL_LONG ( param , queue - > signo ) ;
/* Call php signal handler - Note that we do not report errors, and we ignore the return value */
/* FIXME: this is probably broken when multiple signals are handled in this while loop (retval) */
call_user_function ( EG ( function_table ) , NULL , * handle , retval , 1 , & param TSRMLS_CC ) ;
2006-05-31 01:40:52 +08:00
zval_ptr_dtor ( & param ) ;
zval_ptr_dtor ( & retval ) ;
2001-06-20 05:42:57 +08:00
}
2002-05-07 07:01:46 +08:00
2005-05-07 22:58:12 +08:00
next = queue - > next ;
queue - > next = PCNTL_G ( spares ) ;
PCNTL_G ( spares ) = queue ;
queue = next ;
2001-06-20 05:42:57 +08:00
}
/* Re-enable queue */
2002-03-17 06:31:57 +08:00
PCNTL_G ( processing_signal_queue ) = 0 ;
2010-11-02 06:43:59 +08:00
/* return signal mask to previous state */
sigprocmask ( SIG_SETMASK , & old_mask , NULL ) ;
2001-06-20 05:42:57 +08:00
}
2005-05-07 22:58:12 +08:00
2001-06-12 16:54:25 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/