mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
pcntl: Adding pcntl_rfork support.
This commit is contained in:
parent
20ef668978
commit
28382aa1ec
7 changed files with 144 additions and 1 deletions
|
@ -346,6 +346,9 @@ PHP 8.1 UPGRADE NOTES
|
|||
. Added array_is_list(array $array), which will return true if the array keys are 0 .. count($array)-1 in that order.
|
||||
RFC: https://wiki.php.net/rfc/is_list
|
||||
|
||||
- pcntl:
|
||||
. Added pcntl_rfork for FreeBSD variants
|
||||
|
||||
- Reflection:
|
||||
. Added ReflectionFunctionAbstract::getClosureUsedVariables
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ if test "$PHP_PCNTL" != "no"; then
|
|||
AC_CHECK_FUNCS([fork], [], [AC_MSG_ERROR([pcntl: fork() not supported by this platform])])
|
||||
AC_CHECK_FUNCS([waitpid], [], [AC_MSG_ERROR([pcntl: waitpid() not supported by this platform])])
|
||||
AC_CHECK_FUNCS([sigaction], [], [AC_MSG_ERROR([pcntl: sigaction() not supported by this platform])])
|
||||
AC_CHECK_FUNCS([getpriority setpriority wait3 wait4 sigwaitinfo sigtimedwait unshare])
|
||||
AC_CHECK_FUNCS([getpriority setpriority wait3 wait4 sigwaitinfo sigtimedwait unshare rfork])
|
||||
|
||||
AC_MSG_CHECKING([for siginfo_t])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
|
|
|
@ -340,6 +340,36 @@ void php_register_signal_constants(INIT_FUNC_ARGS)
|
|||
REGISTER_LONG_CONSTANT("CLONE_NEWCGROUP", CLONE_NEWCGROUP, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RFORK
|
||||
#ifdef RFPROC
|
||||
REGISTER_LONG_CONSTANT("RFPROC", RFPROC, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#ifdef RFNOWAIT
|
||||
REGISTER_LONG_CONSTANT("RFNOWAIT", RFNOWAIT, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#ifdef RFCFDG
|
||||
REGISTER_LONG_CONSTANT("RFCFDG", RFCFDG, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#ifdef RFFDG
|
||||
REGISTER_LONG_CONSTANT("RFFDG", RFFDG, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#ifdef RFLINUXTHPN
|
||||
REGISTER_LONG_CONSTANT("RFLINUXTHPN", RFLINUXTHPN, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#ifdef RFMEM
|
||||
REGISTER_LONG_CONSTANT("RFMEM", RFMEM, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#ifdef RFSIGSHARE
|
||||
REGISTER_LONG_CONSTANT("RFSIGSHARE", RFSIGSHARE, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#ifdef RFSIGZMB
|
||||
REGISTER_LONG_CONSTANT("RFSIGSZMB", RFSIGSZMB, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#ifdef RFTHREAD
|
||||
REGISTER_LONG_CONSTANT("RFTHREAD", RFTHREAD, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void php_pcntl_register_errno_constants(INIT_FUNC_ARGS)
|
||||
|
@ -1468,6 +1498,54 @@ PHP_FUNCTION(pcntl_unshare)
|
|||
/* }}} */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RFORK
|
||||
/* {{{ proto bool pcntl_rfork([int flags|custom signal)
|
||||
More control over the process creation is given over fork/vfork. */
|
||||
PHP_FUNCTION(pcntl_rfork)
|
||||
{
|
||||
zend_long flags;
|
||||
zend_long csignal;
|
||||
pid_t pid;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 2)
|
||||
Z_PARAM_LONG(flags)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_LONG(csignal)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
/* This is a flag to use with great caution in general, preferably not within PHP */
|
||||
if ((flags & RFMEM) != 0) {
|
||||
flags &= ~RFMEM;
|
||||
}
|
||||
|
||||
/* A new pid is required */
|
||||
flags |= RFPROC;
|
||||
|
||||
if (ZEND_NUM_ARGS() == 2 && (flags & RFTSIGZMB) != 0) {
|
||||
flags |= RFTSIGFLAGS(csignal);
|
||||
}
|
||||
|
||||
pid = rfork(flags);
|
||||
|
||||
if (pid == -1) {
|
||||
PCNTL_G(last_error) = errno;
|
||||
switch (errno) {
|
||||
case EINVAL:
|
||||
php_error_docref(NULL, E_WARNING, "RFFDG and RFCFDG modes are mutually exclusive");
|
||||
break;
|
||||
case EAGAIN:
|
||||
php_error_docref(NULL, E_WARNING, "Maximum process creations limit reached\n");
|
||||
break;
|
||||
default:
|
||||
php_error_docref(NULL, E_WARNING, "Error %d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_LONG((zend_long) pid);
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
static void pcntl_interrupt_function(zend_execute_data *execute_data)
|
||||
{
|
||||
pcntl_signal_dispatch();
|
||||
|
|
|
@ -79,3 +79,7 @@ function pcntl_async_signals(?bool $enable = null): bool {}
|
|||
#ifdef HAVE_UNSHARE
|
||||
function pcntl_unshare(int $flags): bool {}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RFORK
|
||||
function pcntl_rfork(int $flags, int $signal): int{}
|
||||
#endif
|
||||
|
|
|
@ -119,6 +119,13 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pcntl_unshare, 0, 1, _IS_BOOL, 0
|
|||
ZEND_END_ARG_INFO()
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_RFORK)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pcntl_rfork, 0, 1, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, signal, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
#endif
|
||||
|
||||
|
||||
ZEND_FUNCTION(pcntl_fork);
|
||||
ZEND_FUNCTION(pcntl_waitpid);
|
||||
|
@ -158,6 +165,9 @@ ZEND_FUNCTION(pcntl_async_signals);
|
|||
#if defined(HAVE_UNSHARE)
|
||||
ZEND_FUNCTION(pcntl_unshare);
|
||||
#endif
|
||||
#if defined(HAVE_RFORK)
|
||||
ZEND_FUNCTION(pcntl_rfork);
|
||||
#endif
|
||||
|
||||
|
||||
static const zend_function_entry ext_functions[] = {
|
||||
|
|
24
ext/pcntl/tests/pcntl_rfork.phpt
Normal file
24
ext/pcntl/tests/pcntl_rfork.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Test function pcntl_rfork() with no flag.
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pcntl')) die('skip pcntl extension not available');
|
||||
elseif (!extension_loaded('posix')) die('skip posix extension not available');
|
||||
if (!function_exists('pcntl_rfork')) die('skip pcntl_rfork unavailable');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
echo "*** Test with no flags ***\n";
|
||||
|
||||
$pid = pcntl_rfork(0);
|
||||
if ($pid > 0) {
|
||||
pcntl_wait($status);
|
||||
var_dump($pid);
|
||||
} else {
|
||||
var_dump($pid);
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
*** Test with no flags ***
|
||||
int(0)
|
||||
int(%d)
|
24
ext/pcntl/tests/pcntl_rfork_nowait.phpt
Normal file
24
ext/pcntl/tests/pcntl_rfork_nowait.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Test function pcntl_rfork() with no wait flag.
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pcntl')) die('skip pcntl extension not available');
|
||||
elseif (!extension_loaded('posix')) die('skip posix extension not available');
|
||||
if (!function_exists('pcntl_rfork')) die('skip pcntl_rfork unavailable');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
echo "*** Test by with child not reporting to the parent ***\n";
|
||||
|
||||
$pid = pcntl_rfork(RFNOWAIT|RFTSIGZMB,SIGUSR1);
|
||||
if ($pid > 0) {
|
||||
var_dump($pid);
|
||||
} else {
|
||||
var_dump($pid);
|
||||
sleep(1);
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
*** Test by with child not reporting to the parent ***
|
||||
int(%d)
|
||||
int(0)
|
Loading…
Add table
Add a link
Reference in a new issue