pcntl add forkx for solaris based systems. (#7654)

This commit is contained in:
David CARLIER 2021-11-30 14:47:14 +00:00 committed by GitHub
parent 032de9e001
commit 283669f1ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 1 deletions

View file

@ -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 rfork])
AC_CHECK_FUNCS([getpriority setpriority wait3 wait4 sigwaitinfo sigtimedwait unshare rfork forkx])
AC_MSG_CHECKING([for siginfo_t])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[

View file

@ -46,6 +46,10 @@
#include <sched.h>
#endif
#ifdef HAVE_FORKX
#include <sys/fork.h>
#endif
#ifndef NSIG
# define NSIG 32
#endif
@ -364,6 +368,11 @@ void php_register_signal_constants(INIT_FUNC_ARGS)
REGISTER_LONG_CONSTANT("RFTHREAD", RFTHREAD, CONST_CS | CONST_PERSISTENT);
#endif
#endif
#ifdef HAVE_FORKX
REGISTER_LONG_CONSTANT("FORK_NOSIGCHLD", FORK_NOSIGCHLD, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FORK_WAITPID", FORK_WAITPID, CONST_CS | CONST_PERSISTENT);
#endif
}
static void php_pcntl_register_errno_constants(INIT_FUNC_ARGS)
@ -1551,6 +1560,49 @@ PHP_FUNCTION(pcntl_rfork)
#endif
/* }}} */
#ifdef HAVE_FORKX
/* {{{ proto bool pcntl_forkx(int flags)
More elaborated version of fork with the following settings.
FORK_WAITPID: forbid the parent process to wait for multiple pid but one only
FORK_NOSIGCHLD: SIGCHLD signal ignored when the child terminates */
PHP_FUNCTION(pcntl_forkx)
{
zend_long flags;
pid_t pid;
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_LONG(flags)
ZEND_PARSE_PARAMETERS_END();
if (flags < FORK_NOSIGCHLD || flags > FORK_WAITPID) {
zend_argument_value_error(1, "must be FORK_NOSIGCHLD or FORK_WAITPID");
RETURN_THROWS();
}
pid = forkx(flags);
if (pid == -1) {
PCNTL_G(last_error) = errno;
switch (errno) {
case EAGAIN:
php_error_docref(NULL, E_WARNING, "Maximum process creations limit reached\n");
break;
case EPERM:
php_error_docref(NULL, E_WARNING, "Calling process not having the proper privileges\n");
break;
case ENOMEM:
php_error_docref(NULL, E_WARNING, "No swap space left\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();

View file

@ -83,3 +83,7 @@ function pcntl_unshare(int $flags): bool {}
#ifdef HAVE_RFORK
function pcntl_rfork(int $flags, int $signal = 0): int{}
#endif
#
#ifdef HAVE_RFORK
function pcntl_forkx(int $flags): int{}
#endif

View file

@ -125,6 +125,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pcntl_rfork, 0, 1, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, signal, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
#endif
#if defined(HAVE_FORKX)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pcntl_forkx, 0, 0, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
ZEND_END_ARG_INFO()
#endif
ZEND_FUNCTION(pcntl_fork);