2001-06-12 16:54:25 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-09-20 00:33:14 +08:00
| PHP Version 7 |
2001-06-12 16:54:25 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2018-01-02 12:53:31 +08:00
| Copyright ( c ) 1997 - 2018 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:10:17 +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 )
2014-12-11 22:01:55 +08:00
ZEND_ARG_INFO ( 1 , rusage )
2008-06-30 21:15:03 +08:00
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 )
2014-12-11 22:01:55 +08:00
ZEND_ARG_INFO ( 1 , rusage )
2008-06-30 21:15:03 +08:00
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 ( )
2016-07-03 00:44:17 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_signal_get_handler , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , signo )
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 ( )
2016-06-14 06:33:19 +08:00
# ifdef HAVE_STRUCT_SIGINFO_T
# if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
2008-07-30 00:59:10 +08:00
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 ( )
2016-06-14 06:33:19 +08:00
# endif
# endif
2008-07-30 00:59:10 +08:00
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 ( )
2015-02-23 21:38:55 +08:00
# ifdef HAVE_WCONTINUED
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_wifcontinued , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , status )
ZEND_END_ARG_INFO ( )
# endif
2008-06-30 21:15:03 +08:00
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:10:17 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_strerror , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , errno )
ZEND_END_ARG_INFO ( )
2016-07-06 18:11:47 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pcntl_async_signals , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , on )
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 )
2016-07-03 00:44:17 +08:00
PHP_FE ( pcntl_signal_get_handler , arginfo_pcntl_signal_get_handler )
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:10:17 +08:00
PHP_FE ( pcntl_get_last_error , arginfo_pcntl_void )
PHP_FALIAS ( pcntl_errno , pcntl_get_last_error , NULL )
2015-02-23 21:38:55 +08:00
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
2016-06-14 06:33:19 +08:00
# ifdef HAVE_STRUCT_SIGINFO_T
# if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
2008-07-30 00:59:10 +08:00
PHP_FE ( pcntl_sigwaitinfo , arginfo_pcntl_sigwaitinfo )
PHP_FE ( pcntl_sigtimedwait , arginfo_pcntl_sigtimedwait )
2016-06-14 06:33:19 +08:00
# endif
2015-02-23 21:38:55 +08:00
# endif
# ifdef HAVE_WCONTINUED
PHP_FE ( pcntl_wifcontinued , arginfo_pcntl_wifcontinued )
2004-08-28 20:20:06 +08:00
# endif
2016-07-06 18:11:47 +08:00
PHP_FE ( pcntl_async_signals , arginfo_pcntl_async_signals )
2011-07-25 19:35:02 +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 ) ,
2015-03-24 03:54:55 +08:00
PHP_PCNTL_VERSION ,
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
2016-07-06 18:11:47 +08:00
static void ( * orig_interrupt_function ) ( zend_execute_data * execute_data ) ;
2016-06-14 06:33:19 +08:00
# ifdef HAVE_STRUCT_SIGINFO_T
static void pcntl_signal_handler ( int , siginfo_t * , void * ) ;
static void pcntl_siginfo_to_zval ( int , siginfo_t * , zval * ) ;
# else
2003-05-30 07:39:41 +08:00
static void pcntl_signal_handler ( int ) ;
2016-06-14 06:33:19 +08:00
# endif
2008-07-30 00:46:11 +08:00
static void pcntl_signal_dispatch ( ) ;
2016-07-06 18:11:47 +08:00
static void pcntl_interrupt_function ( zend_execute_data * execute_data ) ;
2015-01-03 17:22:58 +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
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " WNOHANG " , ( zend_long ) WNOHANG , CONST_CS | CONST_PERSISTENT ) ;
2001-07-06 13:48:52 +08:00
# endif
# ifdef WUNTRACED
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " WUNTRACED " , ( zend_long ) WUNTRACED , CONST_CS | CONST_PERSISTENT ) ;
2001-07-06 13:48:52 +08:00
# endif
2015-02-23 21:38:55 +08:00
# ifdef HAVE_WCONTINUED
REGISTER_LONG_CONSTANT ( " WCONTINUED " , ( zend_long ) WCONTINUED , CONST_CS | CONST_PERSISTENT ) ;
# endif
2001-07-06 13:48:52 +08:00
/* Signal Constants */
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIG_IGN " , ( zend_long ) SIG_IGN , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIG_DFL " , ( zend_long ) SIG_DFL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIG_ERR " , ( zend_long ) SIG_ERR , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGHUP " , ( zend_long ) SIGHUP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGINT " , ( zend_long ) SIGINT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGQUIT " , ( zend_long ) SIGQUIT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGILL " , ( zend_long ) SIGILL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTRAP " , ( zend_long ) SIGTRAP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGABRT " , ( zend_long ) SIGABRT , CONST_CS | CONST_PERSISTENT ) ;
2002-12-12 20:23:32 +08:00
# ifdef SIGIOT
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIGIOT " , ( zend_long ) SIGIOT , CONST_CS | CONST_PERSISTENT ) ;
# endif
REGISTER_LONG_CONSTANT ( " SIGBUS " , ( zend_long ) SIGBUS , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGFPE " , ( zend_long ) SIGFPE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGKILL " , ( zend_long ) SIGKILL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGUSR1 " , ( zend_long ) SIGUSR1 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGSEGV " , ( zend_long ) SIGSEGV , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGUSR2 " , ( zend_long ) SIGUSR2 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGPIPE " , ( zend_long ) SIGPIPE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGALRM " , ( zend_long ) SIGALRM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTERM " , ( zend_long ) SIGTERM , CONST_CS | CONST_PERSISTENT ) ;
2001-06-13 09:13:05 +08:00
# ifdef SIGSTKFLT
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIGSTKFLT " , ( zend_long ) SIGSTKFLT , CONST_CS | CONST_PERSISTENT ) ;
2015-01-03 17:22:58 +08:00
# endif
2001-06-13 09:13:05 +08:00
# ifdef SIGCLD
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIGCLD " , ( zend_long ) SIGCLD , CONST_CS | CONST_PERSISTENT ) ;
2001-06-13 09:13:05 +08:00
# endif
# ifdef SIGCHLD
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIGCHLD " , ( zend_long ) SIGCHLD , CONST_CS | CONST_PERSISTENT ) ;
# endif
REGISTER_LONG_CONSTANT ( " SIGCONT " , ( zend_long ) SIGCONT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGSTOP " , ( zend_long ) SIGSTOP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTSTP " , ( zend_long ) SIGTSTP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTTIN " , ( zend_long ) SIGTTIN , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGTTOU " , ( zend_long ) SIGTTOU , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGURG " , ( zend_long ) SIGURG , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGXCPU " , ( zend_long ) SIGXCPU , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGXFSZ " , ( zend_long ) SIGXFSZ , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGVTALRM " , ( zend_long ) SIGVTALRM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGPROF " , ( zend_long ) SIGPROF , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGWINCH " , ( zend_long ) SIGWINCH , CONST_CS | CONST_PERSISTENT ) ;
2001-06-26 12:54:47 +08:00
# ifdef SIGPOLL
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIGPOLL " , ( zend_long ) SIGPOLL , CONST_CS | CONST_PERSISTENT ) ;
2001-06-26 12:54:47 +08:00
# endif
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIGIO " , ( zend_long ) SIGIO , CONST_CS | CONST_PERSISTENT ) ;
2001-06-26 12:54:47 +08:00
# ifdef SIGPWR
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIGPWR " , ( zend_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
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIGSYS " , ( zend_long ) SIGSYS , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SIGBABY " , ( zend_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
2014-08-26 01:24:55 +08:00
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 ) ;
2003-02-18 09:41:06 +08:00
# endif
2008-07-30 00:59:10 +08:00
/* {{{ "how" argument for sigprocmask */
# ifdef HAVE_SIGPROCMASK
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SIG_BLOCK " , SIG_BLOCK , CONST_CS | CONST_PERSISTENT ) ;
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
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SI_USER " , SI_USER , CONST_CS | CONST_PERSISTENT ) ;
2008-07-30 00:59:10 +08:00
# ifdef SI_NOINFO
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SI_NOINFO " , SI_NOINFO , CONST_CS | CONST_PERSISTENT ) ;
2008-07-30 00:59:10 +08:00
# endif
# ifdef SI_KERNEL
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SI_KERNEL " , SI_KERNEL , CONST_CS | CONST_PERSISTENT ) ;
2008-07-30 00:59:10 +08:00
# endif
2014-08-26 01:24:55 +08:00
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 ) ;
2008-07-30 00:59:10 +08:00
# ifdef SI_SIGIO
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SI_SIGIO " , SI_SIGIO , CONST_CS | CONST_PERSISTENT ) ;
2008-07-30 00:59:10 +08:00
# endif
# ifdef SI_TKILL
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SI_TKILL " , SI_TKILL , CONST_CS | CONST_PERSISTENT ) ;
2008-07-30 00:59:10 +08:00
# endif
/* si_code for SIGCHILD */
2009-03-26 07:34:08 +08:00
# ifdef CLD_EXITED
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +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
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " BUS_OBJERR " , BUS_OBJERR , CONST_CS | CONST_PERSISTENT ) ;
2008-07-30 00:59:10 +08:00
# 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:10:17 +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 )
2015-01-03 17:22:58 +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 ;
2016-07-06 18:11:47 +08:00
PCNTL_G ( async_signals ) = 0 ;
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:10:17 +08:00
php_pcntl_register_errno_constants ( INIT_FUNC_ARGS_PASSTHRU ) ;
2015-09-28 17:21:17 +08:00
php_add_tick_function ( pcntl_signal_dispatch , NULL ) ;
2016-07-06 18:11:47 +08:00
orig_interrupt_function = zend_interrupt_function ;
zend_interrupt_function = pcntl_interrupt_function ;
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:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Error %d " , errno ) ;
2001-06-12 16:54:25 +08:00
}
2015-01-03 17:22:58 +08:00
2014-08-26 17:23:25 +08:00
RETURN_LONG ( ( zend_long ) id ) ;
2001-06-12 16:54:25 +08:00
}
/* }}} */
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 )
{
2014-08-26 01:24:55 +08:00
zend_long seconds ;
2002-06-04 23:51:25 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & seconds ) = = FAILURE )
2002-06-04 23:51:25 +08:00
return ;
2015-01-03 17:22:58 +08:00
2014-08-26 01:24:55 +08:00
RETURN_LONG ( ( zend_long ) alarm ( seconds ) ) ;
2002-06-04 23:51:25 +08:00
}
/* }}} */
2014-12-11 22:01:55 +08:00
# define PHP_RUSAGE_PARA(from, to, field) \
add_assoc_long ( to , # field , from . field )
# if !defined(_OSD_POSIX) && !defined(__BEOS__) /* BS2000 has only a few fields in the rusage struct */
# define PHP_RUSAGE_SPECIAL(from, to) \
PHP_RUSAGE_PARA ( from , to , ru_oublock ) ; \
PHP_RUSAGE_PARA ( from , to , ru_inblock ) ; \
PHP_RUSAGE_PARA ( from , to , ru_msgsnd ) ; \
PHP_RUSAGE_PARA ( from , to , ru_msgrcv ) ; \
PHP_RUSAGE_PARA ( from , to , ru_maxrss ) ; \
PHP_RUSAGE_PARA ( from , to , ru_ixrss ) ; \
PHP_RUSAGE_PARA ( from , to , ru_idrss ) ; \
PHP_RUSAGE_PARA ( from , to , ru_minflt ) ; \
PHP_RUSAGE_PARA ( from , to , ru_majflt ) ; \
PHP_RUSAGE_PARA ( from , to , ru_nsignals ) ; \
PHP_RUSAGE_PARA ( from , to , ru_nvcsw ) ; \
PHP_RUSAGE_PARA ( from , to , ru_nivcsw ) ; \
PHP_RUSAGE_PARA ( from , to , ru_nswap ) ;
# else /*_OSD_POSIX*/
# define PHP_RUSAGE_SPECIAL(from, to)
# endif
# define PHP_RUSAGE_COMMON(from ,to) \
PHP_RUSAGE_PARA ( from , to , ru_utime . tv_usec ) ; \
PHP_RUSAGE_PARA ( from , to , ru_utime . tv_sec ) ; \
PHP_RUSAGE_PARA ( from , to , ru_stime . tv_usec ) ; \
PHP_RUSAGE_PARA ( from , to , ru_stime . tv_sec ) ;
# define PHP_RUSAGE_TO_ARRAY(from, to) \
if ( to ) { \
PHP_RUSAGE_SPECIAL ( from , to ) \
PHP_RUSAGE_COMMON ( from , to ) ; \
}
/* {{{ proto int pcntl_waitpid(int pid, int &status, int options, array &$rusage)
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 )
{
2014-08-26 01:24:55 +08:00
zend_long pid , options = 0 ;
2014-12-11 22:01:55 +08:00
zval * z_status = NULL , * z_rusage = NULL ;
2002-04-24 05:21:41 +08:00
int status ;
pid_t child_id ;
2014-12-11 22:01:55 +08:00
# ifdef HAVE_WAIT4
struct rusage rusage ;
# endif
2001-06-12 16:54:25 +08:00
2016-05-05 15:18:17 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " lz/|lz/ " , & pid , & z_status , & options , & z_rusage ) = = FAILURE ) {
2002-04-24 05:21:41 +08:00
return ;
2016-05-05 15:18:17 +08:00
}
2015-01-03 17:22:58 +08:00
2016-05-05 15:18:17 +08:00
status = zval_get_long ( z_status ) ;
2001-06-12 16:54:25 +08:00
2014-12-11 22:01:55 +08:00
# ifdef HAVE_WAIT4
if ( z_rusage ) {
if ( Z_TYPE_P ( z_rusage ) ! = IS_ARRAY ) {
zval_dtor ( z_rusage ) ;
array_init ( z_rusage ) ;
} else {
zend_hash_clean ( Z_ARRVAL_P ( z_rusage ) ) ;
}
memset ( & rusage , 0 , sizeof ( struct rusage ) ) ;
child_id = wait4 ( ( pid_t ) pid , & status , options , & rusage ) ;
} else {
child_id = waitpid ( ( pid_t ) pid , & status , options ) ;
}
# else
2002-04-24 05:21:41 +08:00
child_id = waitpid ( ( pid_t ) pid , & status , options ) ;
2014-12-11 22:01:55 +08:00
# endif
2002-04-24 05:21:41 +08:00
2010-11-02 04:10:17 +08:00
if ( child_id < 0 ) {
PCNTL_G ( last_error ) = errno ;
}
2014-12-11 22:01:55 +08:00
# ifdef HAVE_WAIT4
if ( child_id > 0 ) {
PHP_RUSAGE_TO_ARRAY ( rusage , z_rusage ) ;
}
# endif
2016-05-05 15:18:17 +08:00
zval_dtor ( z_status ) ;
ZVAL_LONG ( z_status , status ) ;
2002-04-24 05:21:41 +08:00
2014-08-26 01:24:55 +08:00
RETURN_LONG ( ( zend_long ) child_id ) ;
2001-06-12 16:54:25 +08:00
}
/* }}} */
2014-12-11 22:01:55 +08:00
/* {{{ proto int pcntl_wait(int &status, int $options, array &$rusage)
2003-10-29 01:08:18 +08:00
Waits on or returns the status of a forked child as defined by the waitpid ( ) system call */
PHP_FUNCTION ( pcntl_wait )
{
2014-08-26 01:24:55 +08:00
zend_long options = 0 ;
2014-12-11 22:01:55 +08:00
zval * z_status = NULL , * z_rusage = NULL ;
2003-10-29 01:08:18 +08:00
int status ;
pid_t child_id ;
2014-12-11 22:01:55 +08:00
# ifdef HAVE_WAIT3
struct rusage rusage ;
# endif
2003-10-29 01:08:18 +08:00
2016-05-05 15:18:17 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " z/|lz/ " , & z_status , & options , & z_rusage ) = = FAILURE ) {
2003-10-29 01:08:18 +08:00
return ;
2016-05-05 15:18:17 +08:00
}
2015-01-03 17:22:58 +08:00
2016-05-05 15:18:17 +08:00
status = zval_get_long ( z_status ) ;
2003-10-29 01:08:18 +08:00
# ifdef HAVE_WAIT3
2014-12-11 22:01:55 +08:00
if ( z_rusage ) {
if ( Z_TYPE_P ( z_rusage ) ! = IS_ARRAY ) {
zval_dtor ( z_rusage ) ;
array_init ( z_rusage ) ;
} else {
zend_hash_clean ( Z_ARRVAL_P ( z_rusage ) ) ;
}
memset ( & rusage , 0 , sizeof ( struct rusage ) ) ;
child_id = wait3 ( & status , options , & rusage ) ;
} else if ( options ) {
child_id = wait3 ( & status , options , NULL ) ;
} else {
2003-10-29 01:08:18 +08:00
child_id = wait ( & status ) ;
}
# else
child_id = wait ( & status ) ;
# endif
2010-11-02 04:10:17 +08:00
if ( child_id < 0 ) {
PCNTL_G ( last_error ) = errno ;
}
2014-12-11 22:01:55 +08:00
# ifdef HAVE_WAIT3
if ( child_id > 0 ) {
PHP_RUSAGE_TO_ARRAY ( rusage , z_rusage ) ;
}
# endif
2016-05-05 15:18:17 +08:00
zval_dtor ( z_status ) ;
ZVAL_LONG ( z_status , status ) ;
2003-10-29 01:08:18 +08:00
2014-08-26 01:24:55 +08:00
RETURN_LONG ( ( zend_long ) child_id ) ;
2003-10-29 01:08:18 +08:00
}
/* }}} */
2014-12-11 22:01:55 +08:00
# undef PHP_RUSAGE_PARA
# undef PHP_RUSAGE_SPECIAL
# undef PHP_RUSAGE_COMMON
# undef PHP_RUSAGE_TO_ARRAY
/* {{{ 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
2014-08-26 01:24:55 +08:00
zend_long status_word ;
2008-06-22 23:16:11 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & status_word ) = = FAILURE ) {
2008-06-22 23:16:11 +08:00
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
2018-02-23 23:11:18 +08:00
if ( WIFEXITED ( ( int ) status_word ) )
2008-06-22 23:16:11 +08:00
RETURN_TRUE ;
2001-07-06 13:48:52 +08:00
# endif
2018-02-23 23:11:18 +08:00
2001-07-06 13:48:52 +08:00
RETURN_FALSE ;
}
/* }}} */
2015-01-03 17:22:58 +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
2014-08-26 01:24:55 +08:00
zend_long status_word ;
2008-06-22 23:16:11 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & status_word ) = = FAILURE ) {
2008-06-22 23:16:11 +08:00
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
2018-02-23 23:11:18 +08:00
if ( WIFSTOPPED ( ( int ) status_word ) )
2008-06-22 23:16:11 +08:00
RETURN_TRUE ;
2001-07-06 13:48:52 +08:00
# endif
RETURN_FALSE ;
}
/* }}} */
2015-01-03 17:22:58 +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
2014-08-26 01:24:55 +08:00
zend_long status_word ;
2008-06-22 23:16:11 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & status_word ) = = FAILURE ) {
2008-06-22 23:16:11 +08:00
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
2018-02-23 23:11:18 +08:00
if ( WIFSIGNALED ( ( int ) status_word ) )
2008-06-22 23:16:11 +08:00
RETURN_TRUE ;
2001-07-06 13:48:52 +08:00
# endif
RETURN_FALSE ;
}
/* }}} */
2015-02-23 21:38:55 +08:00
/* {{{ proto bool pcntl_wifcontinued(int status)
Returns true if the child status code represents a process that was resumed due to a SIGCONT signal */
PHP_FUNCTION ( pcntl_wifcontinued )
{
# ifdef HAVE_WCONTINUED
zend_long status_word ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & status_word ) = = FAILURE ) {
return ;
}
2018-02-23 23:11:18 +08:00
if ( WIFCONTINUED ( ( int ) status_word ) )
2015-02-23 21:38:55 +08:00
RETURN_TRUE ;
# endif
RETURN_FALSE ;
}
/* }}} */
2001-07-06 13:48:52 +08:00
2015-01-03 17:22:58 +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
2014-08-26 01:24:55 +08:00
zend_long status_word ;
2008-06-22 23:16:11 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & status_word ) = = FAILURE ) {
2008-06-22 23:16:11 +08:00
return ;
2001-07-06 13:48:52 +08:00
}
2018-02-23 23:11:18 +08:00
RETURN_LONG ( WEXITSTATUS ( ( int ) status_word ) ) ;
2001-07-06 13:48:52 +08:00
# else
RETURN_FALSE ;
# endif
}
/* }}} */
2015-01-03 17:22:58 +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
2014-08-26 01:24:55 +08:00
zend_long status_word ;
2008-06-22 23:16:11 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & status_word ) = = FAILURE ) {
2008-06-22 23:16:11 +08:00
return ;
2001-07-06 13:48:52 +08:00
}
2008-06-22 23:16:11 +08:00
2018-02-23 23:11:18 +08:00
RETURN_LONG ( WTERMSIG ( ( int ) status_word ) ) ;
2001-07-06 13:48:52 +08:00
# else
RETURN_FALSE ;
# endif
}
/* }}} */
2015-01-03 17:22:58 +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
2014-08-26 01:24:55 +08:00
zend_long status_word ;
2008-06-22 23:16:11 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & status_word ) = = FAILURE ) {
2008-06-22 23:16:11 +08:00
return ;
2001-07-06 13:48:52 +08:00
}
2018-02-23 23:11:18 +08:00
RETURN_LONG ( WSTOPSIG ( ( int ) 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 ;
2014-05-06 18:23:56 +08:00
zval * element ;
2001-09-30 14:59:12 +08:00
HashTable * args_hash , * envs_hash ;
2002-03-17 06:31:57 +08:00
int argc = 0 , argi = 0 ;
int envc = 0 , envi = 0 ;
char * * argv = NULL , * * envp = NULL ;
char * * current_arg , * * pair ;
2001-09-30 14:59:12 +08:00
int pair_length ;
2014-05-06 18:23:56 +08:00
zend_string * key ;
2001-09-30 14:59:12 +08:00
char * path ;
2014-08-27 21:31:48 +08:00
size_t path_len ;
2014-08-26 01:24:55 +08:00
zend_ulong key_num ;
2015-01-03 17:22:58 +08:00
2015-05-13 05:31:52 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " p|aa " , & path , & path_len , & args , & envs ) = = FAILURE ) {
2001-09-30 14:59:12 +08:00
return ;
}
2015-01-03 17:22:58 +08:00
2002-03-17 06:31:57 +08:00
if ( ZEND_NUM_ARGS ( ) > 1 ) {
2012-03-28 22:18:23 +08:00
/* Build argument list */
2015-09-25 03:39:59 +08:00
args_hash = Z_ARRVAL_P ( args ) ;
2002-03-17 06:31:57 +08:00
argc = zend_hash_num_elements ( args_hash ) ;
2015-01-03 17:22:58 +08:00
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 ;
2014-05-28 21:30:05 +08:00
current_arg = argv + 1 ;
ZEND_HASH_FOREACH_VAL ( args_hash , element ) {
if ( argi > = argc ) break ;
2002-05-07 03:48:39 +08:00
convert_to_string_ex ( element ) ;
2014-05-06 18:23:56 +08:00
* current_arg = Z_STRVAL_P ( element ) ;
2014-05-28 21:30:05 +08:00
argi + + ;
current_arg + + ;
} ZEND_HASH_FOREACH_END ( ) ;
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 */
2015-09-25 03:39:59 +08:00
envs_hash = Z_ARRVAL_P ( envs ) ;
2002-03-17 06:31:57 +08:00
envc = zend_hash_num_elements ( envs_hash ) ;
2015-01-03 17:22:58 +08:00
pair = envp = safe_emalloc ( ( envc + 1 ) , sizeof ( char * ) , 0 ) ;
2014-05-28 21:30:05 +08:00
ZEND_HASH_FOREACH_KEY_VAL ( envs_hash , key_num , key , element ) {
if ( envi > = envc ) break ;
if ( ! key ) {
2014-08-26 04:47:04 +08:00
key = zend_long_to_str ( key_num ) ;
2014-05-28 21:30:05 +08:00
} else {
2014-08-26 01:24:55 +08:00
zend_string_addref ( key ) ;
2001-09-30 14:59:12 +08:00
}
2002-05-07 03:48:39 +08:00
convert_to_string_ex ( element ) ;
2015-01-03 17:22:58 +08:00
/* Length of element + equal sign + length of key + null */
2015-06-30 09:05:24 +08:00
pair_length = Z_STRLEN_P ( element ) + ZSTR_LEN ( key ) + 2 ;
2002-03-17 06:31:57 +08:00
* pair = emalloc ( pair_length ) ;
2015-06-30 09:05:24 +08:00
strlcpy ( * pair , ZSTR_VAL ( key ) , ZSTR_LEN ( key ) + 1 ) ;
2001-09-30 14:59:12 +08:00
strlcat ( * pair , " = " , pair_length ) ;
2014-05-06 18:23:56 +08:00
strlcat ( * pair , Z_STRVAL_P ( element ) , pair_length ) ;
2015-01-03 17:22:58 +08:00
2001-09-30 14:59:12 +08:00
/* Cleanup */
2014-08-26 01:24:55 +08:00
zend_string_release ( key ) ;
2014-05-28 21:30:05 +08:00
envi + + ;
pair + + ;
} ZEND_HASH_FOREACH_END ( ) ;
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:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Error has occurred: (errno %d) %s " , errno , strerror ( errno ) ) ;
2009-09-30 21:04:28 +08:00
}
2015-01-03 17:22:58 +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:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Error has occurred: (errno %d) %s " , errno , strerror ( errno ) ) ;
2009-09-30 21:04:28 +08:00
}
2002-05-07 03:48:39 +08:00
}
2004-06-30 09:12:06 +08:00
efree ( argv ) ;
2015-01-03 17:22:58 +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 )
{
2014-05-06 18:23:56 +08:00
zval * handle ;
zend_string * func_name ;
2014-08-26 01:24:55 +08:00
zend_long signo ;
2002-08-22 12:20:10 +08:00
zend_bool restart_syscalls = 1 ;
2001-06-12 16:54:25 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " lz|b " , & signo , & handle , & restart_syscalls ) = = FAILURE ) {
2009-03-28 11:12:52 +08:00
return ;
2001-06-12 16:54:25 +08:00
}
2011-06-04 01:18:46 +08:00
if ( signo < 1 | | signo > 32 ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Invalid signal " ) ;
2011-06-04 01:18:46 +08:00
RETURN_FALSE ;
}
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 */
2014-08-26 01:24:55 +08:00
if ( Z_TYPE_P ( handle ) = = IS_LONG ) {
if ( Z_LVAL_P ( handle ) ! = ( zend_long ) SIG_DFL & & Z_LVAL_P ( handle ) ! = ( zend_long ) SIG_IGN ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Invalid value for handle argument specified " ) ;
2011-06-04 01:18:46 +08:00
RETURN_FALSE ;
2001-06-12 16:54:25 +08:00
}
2016-06-14 06:33:19 +08:00
if ( php_signal ( signo , ( Sigfunc * ) Z_LVAL_P ( handle ) , ( int ) restart_syscalls ) = = ( Sigfunc * ) SIG_ERR ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Error assigning signal " ) ;
2002-03-17 06:31:57 +08:00
RETURN_FALSE ;
2001-06-12 16:54:25 +08:00
}
2016-07-03 00:44:17 +08:00
zend_hash_index_update ( & PCNTL_G ( php_signal_table ) , signo , handle ) ;
2001-06-12 16:54:25 +08:00
RETURN_TRUE ;
2002-03-17 06:31:57 +08:00
}
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
if ( ! zend_is_callable ( handle , 0 , & func_name ) ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = EINVAL ;
2015-06-30 09:05:24 +08:00
php_error_docref ( NULL , E_WARNING , " %s is not a callable function name error " , ZSTR_VAL ( func_name ) ) ;
2014-08-26 01:24:55 +08:00
zend_string_release ( func_name ) ;
2001-06-12 16:54:25 +08:00
RETURN_FALSE ;
}
2014-08-26 01:24:55 +08:00
zend_string_release ( func_name ) ;
2015-01-03 17:22:58 +08:00
2002-08-22 12:20:10 +08:00
/* Add the function name to our signal table */
2014-05-06 18:23:56 +08:00
if ( zend_hash_index_update ( & PCNTL_G ( php_signal_table ) , signo , handle ) ) {
if ( Z_REFCOUNTED_P ( handle ) ) Z_ADDREF_P ( handle ) ;
}
2015-01-03 17:22:58 +08:00
2016-06-14 06:33:19 +08:00
if ( php_signal4 ( signo , pcntl_signal_handler , ( int ) restart_syscalls , 1 ) = = ( Sigfunc * ) SIG_ERR ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , 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
}
/* }}} */
2016-07-03 00:44:17 +08:00
/* {{{ proto bool pcntl_signal_get_handler(int signo)
Gets signal handler */
PHP_FUNCTION ( pcntl_signal_get_handler )
{
zval * prev_handle ;
zend_long signo ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & signo ) = = FAILURE ) {
return ;
}
if ( signo < 1 | | signo > 32 ) {
php_error_docref ( NULL , E_WARNING , " Invalid signal " ) ;
RETURN_FALSE ;
}
if ( ( prev_handle = zend_hash_index_find ( & PCNTL_G ( php_signal_table ) , signo ) ) ! = NULL ) {
RETURN_ZVAL ( prev_handle , 1 , 0 ) ;
} else {
2016-07-06 20:54:51 +08:00
RETURN_LONG ( ( zend_long ) SIG_DFL ) ;
2016-07-03 00:44:17 +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 )
{
2014-08-26 01:24:55 +08:00
zend_long how , signo ;
2014-05-06 18:23:56 +08:00
zval * user_set , * user_oldset = NULL , * user_signo ;
2008-11-10 13:57:18 +08:00
sigset_t set , oldset ;
2008-07-30 00:59:10 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " 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:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " %s " , strerror ( errno ) ) ;
2008-07-30 00:59:10 +08:00
RETURN_FALSE ;
}
2014-05-28 21:30:05 +08:00
ZEND_HASH_FOREACH_VAL ( Z_ARRVAL_P ( user_set ) , user_signo ) {
2015-09-29 16:17:43 +08:00
signo = zval_get_long ( user_signo ) ;
2008-07-30 00:59:10 +08:00
if ( sigaddset ( & set , signo ) ! = 0 ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " %s " , strerror ( errno ) ) ;
2008-07-30 00:59:10 +08:00
RETURN_FALSE ;
}
2014-05-28 21:30:05 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2008-07-30 00:59:10 +08:00
2008-11-10 13:57:18 +08:00
if ( sigprocmask ( how , & set , & oldset ) ! = 0 ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " %s " , strerror ( errno ) ) ;
2008-07-30 00:59:10 +08:00
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 ;
}
2014-08-26 01:24:55 +08:00
add_next_index_long ( user_oldset , signo ) ;
2008-11-10 13:57:18 +08:00
}
}
2008-07-30 00:59:10 +08:00
RETURN_TRUE ;
}
/* }}} */
# endif
2016-06-14 06:33:19 +08:00
# ifdef HAVE_STRUCT_SIGINFO_T
# if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
2008-07-30 00:59:10 +08:00
static void pcntl_sigwaitinfo ( INTERNAL_FUNCTION_PARAMETERS , int timedwait ) /* { { { */
{
2014-05-06 18:23:56 +08:00
zval * user_set , * user_signo , * user_siginfo = NULL ;
2014-08-26 01:24:55 +08:00
zend_long tv_sec = 0 , tv_nsec = 0 ;
2008-07-30 00:59:10 +08:00
sigset_t set ;
int signo ;
siginfo_t siginfo ;
struct timespec timeout ;
if ( timedwait ) {
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " a|z/ll " , & user_set , & user_siginfo , & tv_sec , & tv_nsec ) = = FAILURE ) {
2008-07-30 00:59:10 +08:00
return ;
}
} else {
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " a|z/ " , & user_set , & user_siginfo ) = = FAILURE ) {
2008-07-30 00:59:10 +08:00
return ;
}
}
if ( sigemptyset ( & set ) ! = 0 ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " %s " , strerror ( errno ) ) ;
2008-07-30 00:59:10 +08:00
RETURN_FALSE ;
}
2014-05-28 21:30:05 +08:00
ZEND_HASH_FOREACH_VAL ( Z_ARRVAL_P ( user_set ) , user_signo ) {
2015-09-29 16:17:43 +08:00
signo = zval_get_long ( user_signo ) ;
2008-07-30 00:59:10 +08:00
if ( sigaddset ( & set , signo ) ! = 0 ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " %s " , strerror ( errno ) ) ;
2008-07-30 00:59:10 +08:00
RETURN_FALSE ;
}
2014-05-28 21:30:05 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2008-07-30 00:59:10 +08:00
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:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " %s " , strerror ( errno ) ) ;
2008-07-30 00:59:10 +08:00
}
2009-03-28 11:21:04 +08:00
/*
2015-01-03 17:22:58 +08:00
* sigtimedwait and sigwaitinfo can return 0 on success on some
2009-03-28 11:21:04 +08:00
* platforms , e . g . NetBSD
*/
if ( ! signo & & siginfo . si_signo ) {
signo = siginfo . si_signo ;
}
2016-06-14 06:33:19 +08:00
pcntl_siginfo_to_zval ( signo , & siginfo , user_siginfo ) ;
RETURN_LONG ( signo ) ;
}
/* }}} */
/* {{{ proto int pcnlt_sigwaitinfo(array set[, array &siginfo])
Synchronously wait for queued signals */
PHP_FUNCTION ( pcntl_sigwaitinfo )
{
pcntl_sigwaitinfo ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
/* }}} */
/* {{{ proto int pcntl_sigtimedwait(array set[, array &siginfo[, int seconds[, int nanoseconds]]])
Wait for queued signals */
PHP_FUNCTION ( pcntl_sigtimedwait )
{
pcntl_sigwaitinfo ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
/* }}} */
# endif
2009-03-28 11:21:04 +08:00
2016-06-14 06:33:19 +08:00
static void pcntl_siginfo_to_zval ( int signo , siginfo_t * siginfo , zval * user_siginfo ) /* { { { */
{
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
}
2016-06-14 06:33:19 +08:00
add_assoc_long_ex ( user_siginfo , " signo " , sizeof ( " signo " ) - 1 , siginfo - > si_signo ) ;
add_assoc_long_ex ( user_siginfo , " errno " , sizeof ( " errno " ) - 1 , siginfo - > si_errno ) ;
add_assoc_long_ex ( user_siginfo , " code " , sizeof ( " code " ) - 1 , siginfo - > si_code ) ;
2008-07-30 00:59:10 +08:00
switch ( signo ) {
# ifdef SIGCHLD
case SIGCHLD :
2016-06-14 06:33:19 +08:00
add_assoc_long_ex ( user_siginfo , " status " , sizeof ( " status " ) - 1 , siginfo - > si_status ) ;
2008-08-05 23:12:19 +08:00
# ifdef si_utime
2016-06-14 06:33:19 +08:00
add_assoc_double_ex ( user_siginfo , " utime " , sizeof ( " utime " ) - 1 , siginfo - > si_utime ) ;
2008-08-05 23:12:19 +08:00
# endif
# ifdef si_stime
2016-06-14 06:33:19 +08:00
add_assoc_double_ex ( user_siginfo , " stime " , sizeof ( " stime " ) - 1 , siginfo - > si_stime ) ;
2008-08-05 23:12:19 +08:00
# endif
2016-06-14 06:33:19 +08:00
add_assoc_long_ex ( user_siginfo , " pid " , sizeof ( " pid " ) - 1 , siginfo - > si_pid ) ;
add_assoc_long_ex ( user_siginfo , " uid " , sizeof ( " uid " ) - 1 , siginfo - > si_uid ) ;
break ;
case SIGUSR1 :
case SIGUSR2 :
add_assoc_long_ex ( user_siginfo , " pid " , sizeof ( " pid " ) - 1 , siginfo - > si_pid ) ;
add_assoc_long_ex ( user_siginfo , " uid " , sizeof ( " uid " ) - 1 , siginfo - > si_uid ) ;
2008-07-30 00:59:10 +08:00
break ;
# endif
case SIGILL :
case SIGFPE :
case SIGSEGV :
case SIGBUS :
2016-06-14 06:33:19 +08:00
add_assoc_double_ex ( user_siginfo , " addr " , sizeof ( " addr " ) - 1 , ( zend_long ) siginfo - > si_addr ) ;
2008-07-30 00:59:10 +08:00
break ;
# ifdef SIGPOLL
case SIGPOLL :
2016-06-14 06:33:19 +08:00
add_assoc_long_ex ( user_siginfo , " band " , sizeof ( " band " ) - 1 , siginfo - > si_band ) ;
2008-08-05 23:12:19 +08:00
# ifdef si_fd
2016-06-14 06:33:19 +08:00
add_assoc_long_ex ( user_siginfo , " fd " , sizeof ( " fd " ) - 1 , siginfo - > si_fd ) ;
2008-08-05 23:12:19 +08:00
# endif
2008-07-30 00:59:10 +08:00
break ;
# endif
}
}
}
/* }}} */
# 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 )
{
2014-08-26 01:24:55 +08:00
zend_long who = PRIO_PROCESS ;
zend_long pid = getpid ( ) ;
2003-02-18 09:41:06 +08:00
int pri ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |ll " , & pid , & who ) = = FAILURE ) {
2003-02-18 09:41:06 +08:00
RETURN_FALSE ;
}
2015-01-03 17:22:58 +08:00
/* needs to be cleared, since any returned value is valid */
2003-02-18 09:41:06 +08:00
errno = 0 ;
pri = getpriority ( who , pid ) ;
if ( errno ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2003-02-18 09:41:06 +08:00
switch ( errno ) {
case ESRCH :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Error %d: No process was located using the given parameters " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
case EINVAL :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Error %d: Invalid identifier flag " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
default :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Unknown error %d has occurred " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
}
RETURN_FALSE ;
}
2014-08-26 01:24:55 +08:00
RETURN_LONG ( pri ) ;
2003-02-18 09:41:06 +08:00
}
/* }}} */
# 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 )
{
2014-08-26 01:24:55 +08:00
zend_long who = PRIO_PROCESS ;
zend_long pid = getpid ( ) ;
zend_long pri ;
2003-02-18 09:41:06 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l|ll " , & pri , & pid , & who ) = = FAILURE ) {
2003-02-18 09:41:06 +08:00
RETURN_FALSE ;
}
if ( setpriority ( who , pid , pri ) ) {
2010-11-02 04:10:17 +08:00
PCNTL_G ( last_error ) = errno ;
2003-02-18 09:41:06 +08:00
switch ( errno ) {
case ESRCH :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Error %d: No process was located using the given parameters " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
case EINVAL :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Error %d: Invalid identifier flag " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
case EPERM :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , 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 :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , 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 :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Unknown error %d has occurred " , errno ) ;
2003-02-18 09:41:06 +08:00
break ;
}
RETURN_FALSE ;
}
2015-01-03 17:22:58 +08:00
2003-02-18 09:41:06 +08:00
RETURN_TRUE ;
}
/* }}} */
# endif
2010-11-02 04:10:17 +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 )
{
2014-08-26 01:24:55 +08:00
RETURN_LONG ( PCNTL_G ( last_error ) ) ;
2010-11-02 04:10:17 +08:00
}
/* }}} */
/* {{{ proto string pcntl_strerror(int errno)
Retrieve the system error message associated with the given errno . */
PHP_FUNCTION ( pcntl_strerror )
{
2014-08-26 01:24:55 +08:00
zend_long error ;
2010-11-02 04:10:17 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & error ) = = FAILURE ) {
2010-11-02 04:10:17 +08:00
RETURN_FALSE ;
}
2014-05-06 18:23:56 +08:00
RETURN_STRING ( strerror ( error ) ) ;
2010-11-02 04:10:17 +08:00
}
/* }}} */
2001-06-26 01:56:23 +08:00
/* Our custom signal handler that calls the appropriate php_function */
2016-06-14 06:33:19 +08:00
# ifdef HAVE_STRUCT_SIGINFO_T
static void pcntl_signal_handler ( int signo , siginfo_t * siginfo , void * context )
# else
2001-06-20 05:42:57 +08:00
static void pcntl_signal_handler ( int signo )
2016-06-14 06:33:19 +08:00
# endif
2001-06-20 05:42:57 +08:00
{
2005-05-07 22:58:12 +08:00
struct php_pcntl_pending_signal * psig ;
2015-01-03 17:22:58 +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 ;
2016-06-14 06:33:19 +08:00
# ifdef HAVE_STRUCT_SIGINFO_T
2017-01-16 12:32:27 +08:00
psig - > siginfo = * siginfo ;
2016-06-14 06:33:19 +08:00
# endif
2005-05-07 22:58:12 +08:00
/* 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 ;
2014-06-11 23:34:34 +08:00
PCNTL_G ( pending_signals ) = 1 ;
2016-07-06 18:11:47 +08:00
if ( PCNTL_G ( async_signals ) ) {
EG ( vm_interrupt ) = 1 ;
}
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
{
2016-06-14 06:33:19 +08:00
zval params [ 2 ] , * handle , retval ;
2005-05-07 22:58:12 +08:00
struct php_pcntl_pending_signal * queue , * next ;
2010-11-02 06:29:25 +08:00
sigset_t mask ;
sigset_t old_mask ;
2014-06-11 23:34:34 +08:00
if ( ! PCNTL_G ( pending_signals ) ) {
return ;
}
2015-01-03 17:22:58 +08:00
2010-11-02 06:29:25 +08:00
/* Mask all signals */
sigfillset ( & mask ) ;
sigprocmask ( SIG_BLOCK , & mask , & old_mask ) ;
2001-06-20 05:42:57 +08:00
2016-06-14 06:33:19 +08:00
/* Bail if the queue is empty or if we are already playing the queue */
if ( ! PCNTL_G ( head ) | | PCNTL_G ( processing_signal_queue ) ) {
2010-11-02 06:40:29 +08:00
sigprocmask ( SIG_SETMASK , & old_mask , NULL ) ;
2001-06-20 05:42:57 +08:00
return ;
2010-11-02 06:40:29 +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 */
2015-01-03 17:22:58 +08:00
2001-06-20 05:42:57 +08:00
/* Allocate */
2005-05-07 22:58:12 +08:00
while ( queue ) {
2014-05-06 18:23:56 +08:00
if ( ( handle = zend_hash_index_find ( & PCNTL_G ( php_signal_table ) , queue - > signo ) ) ! = NULL ) {
2016-07-06 20:45:20 +08:00
if ( Z_TYPE_P ( handle ) ! = IS_LONG ) {
ZVAL_NULL ( & retval ) ;
2016-06-14 06:33:19 +08:00
ZVAL_LONG ( & params [ 0 ] , queue - > signo ) ;
# ifdef HAVE_STRUCT_SIGINFO_T
2017-01-16 12:32:27 +08:00
array_init ( & params [ 1 ] ) ;
pcntl_siginfo_to_zval ( queue - > signo , & queue - > siginfo , & params [ 1 ] ) ;
2016-06-14 06:33:19 +08:00
# else
ZVAL_NULL ( & params [ 1 ] ) ;
# endif
2016-07-06 20:45:20 +08:00
/* 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) */
2016-06-14 06:33:19 +08:00
call_user_function ( EG ( function_table ) , NULL , handle , & retval , 2 , params ) ;
2016-07-06 20:45:20 +08:00
zval_ptr_dtor ( & retval ) ;
2016-06-14 06:33:19 +08:00
zval_ptr_dtor ( & params [ 0 ] ) ;
zval_ptr_dtor ( & params [ 1 ] ) ;
2016-07-06 20:45:20 +08:00
}
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
}
2014-06-11 23:34:34 +08:00
PCNTL_G ( pending_signals ) = 0 ;
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 ;
2015-01-03 17:22:58 +08:00
2010-11-02 06:29:25 +08:00
/* return signal mask to previous state */
sigprocmask ( SIG_SETMASK , & old_mask , NULL ) ;
2001-06-20 05:42:57 +08:00
}
2016-07-06 18:11:47 +08:00
/* {{{ proto bool pcntl_async_signals([bool on[)
Enable / disable asynchronous signal handling and return the old setting . */
PHP_FUNCTION ( pcntl_async_signals )
{
zend_bool on ;
2005-05-07 22:58:12 +08:00
2016-07-06 18:11:47 +08:00
if ( ZEND_NUM_ARGS ( ) = = 0 ) {
RETURN_BOOL ( PCNTL_G ( async_signals ) ) ;
}
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |b " , & on ) = = FAILURE ) {
return ;
}
RETVAL_BOOL ( PCNTL_G ( async_signals ) ) ;
PCNTL_G ( async_signals ) = on ;
}
/* }}} */
static void pcntl_interrupt_function ( zend_execute_data * execute_data )
{
pcntl_signal_dispatch ( ) ;
if ( orig_interrupt_function ) {
orig_interrupt_function ( execute_data ) ;
}
}
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 :
*/