diff --git a/Zend/zend_mmap.h b/Zend/zend_mmap.h index 53eee61a7ef0c..201fd84d074de 100644 --- a/Zend/zend_mmap.h +++ b/Zend/zend_mmap.h @@ -17,7 +17,7 @@ #include "zend_portability.h" -#ifdef __linux__ +#ifdef HAVE_PRCTL # include /* fallback definitions if our libc is older than the kernel */ @@ -27,7 +27,7 @@ # ifndef PR_SET_VMA_ANON_NAME # define PR_SET_VMA_ANON_NAME 0 # endif -#endif // __linux__ +#endif // HAVE_PRCTL /** * Set a name for the specified memory area. @@ -36,7 +36,7 @@ */ static zend_always_inline void zend_mmap_set_name(const void *start, size_t len, const char *name) { -#ifdef __linux__ +#ifdef HAVE_PRCTL prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (unsigned long)start, len, (unsigned long)name); #endif } diff --git a/build/php.m4 b/build/php.m4 index fb28f462396fc..d3446b0fec471 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -2748,3 +2748,29 @@ AC_DEFUN([PHP_PATCH_CONFIG_HEADERS], [ $SED -e 's/^#undef PACKAGE_[^ ]*/\/\* & \*\//g' < $srcdir/$1 \ > $srcdir/$1.tmp && mv $srcdir/$1.tmp $srcdir/$1 ]) + +dnl Check if we have prctl +AC_DEFUN([PHP_CHECK_PRCTL], +[ + AC_MSG_CHECKING([for prctl]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[prctl(0, 0, 0, 0, 0);]])], [ + AC_DEFINE([HAVE_PRCTL], 1, [do we have prctl?]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl Check if we have procctl +AC_DEFUN([PHP_CHECK_PROCCTL], +[ + AC_MSG_CHECKING([for procctl]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[procctl(0, 0, 0, 0);]])], [ + AC_DEFINE([HAVE_PROCCTL], 1, [do we have procctl?]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/configure.ac b/configure.ac index d39639267ecb0..ff7f1d429614f 100644 --- a/configure.ac +++ b/configure.ac @@ -510,6 +510,10 @@ dnl Check __builtin_cpu_init PHP_CHECK_BUILTIN_CPU_INIT dnl Check __builtin_cpu_supports PHP_CHECK_BUILTIN_CPU_SUPPORTS +dnl Check prctl +PHP_CHECK_PRCTL +dnl Check procctl +PHP_CHECK_PROCCTL dnl Check for __alignof__ support in the compiler AC_CACHE_CHECK(whether the compiler supports __alignof__, ac_cv_alignof_exists,[ diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 66e31323947c4..a727109aa5ee0 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef PHP_WIN32 # include @@ -49,6 +50,14 @@ #include #endif +#ifdef HAVE_PRCTL +# include +#endif + +#ifdef HAVE_PROCCTL +# include +#endif + #include "SAPI.h" #include "php.h" #include "php_ini.h" @@ -2432,6 +2441,24 @@ static char *php_cli_server_parse_addr(const char *addr, int *pport) { return pestrndup(addr, end - addr, 1); } +#if defined(HAVE_PRCTL) || defined(HAVE_PROCCTL) +static void php_cli_server_worker_install_pdeathsig(void) +{ + // Ignore failure to register PDEATHSIG, it's not available on all platforms anyway +#if defined(HAVE_PRCTL) + prctl(PR_SET_PDEATHSIG, SIGTERM); +#elif defined(HAVE_PROCCTL) + int signal = SIGTERM; + procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signal); +#endif + + // Check if parent has exited just after the fork + if (getppid() != php_cli_server_master) { + exit(1); + } +} +#endif + static void php_cli_server_startup_workers(void) { char *workers = getenv("PHP_CLI_SERVER_WORKERS"); if (!workers) { @@ -2459,6 +2486,9 @@ static void php_cli_server_startup_workers(void) { php_cli_server_worker + 1; return; } else if (pid == 0) { +#if defined(HAVE_PRCTL) || defined(HAVE_PROCCTL) + php_cli_server_worker_install_pdeathsig(); +#endif return; } else { php_cli_server_workers[php_cli_server_worker] = pid; diff --git a/sapi/cli/tests/php_cli_server.inc b/sapi/cli/tests/php_cli_server.inc index 65f2cc9a85dd4..d4fca001e505f 100644 --- a/sapi/cli/tests/php_cli_server.inc +++ b/sapi/cli/tests/php_cli_server.inc @@ -4,6 +4,7 @@ class CliServerInfo { public function __construct( public string $docRoot, + public $processHandle, ) {} } @@ -113,7 +114,7 @@ function php_cli_server_start( define("PHP_CLI_SERVER_PORT", $port); define("PHP_CLI_SERVER_ADDRESS", PHP_CLI_SERVER_HOSTNAME.":".PHP_CLI_SERVER_PORT); - return new CliServerInfo($doc_root); + return new CliServerInfo($doc_root, $handle); } function php_cli_server_connect() { diff --git a/sapi/cli/tests/php_cli_server_pdeathsig.phpt b/sapi/cli/tests/php_cli_server_pdeathsig.phpt new file mode 100644 index 0000000000000..8402687c72a50 --- /dev/null +++ b/sapi/cli/tests/php_cli_server_pdeathsig.phpt @@ -0,0 +1,46 @@ +--TEST-- +Killing server should terminate all worker processes +--ENV-- +PHP_CLI_SERVER_WORKERS=2 +--SKIPIF-- + +--FILE-- +processHandle)['pid']; +$workers = find_workers_by_ppid($master); +if (count($workers) === 0) { + throw new \Exception('Could not find worker pids'); +} + +proc_terminate($cliServerInfo->processHandle, 9); // SIGKILL + +$workers = find_workers_by_pids($workers); +if (count($workers) !== 0) { + throw new \Exception('Workers were not properly terminated'); +} + +echo 'Done'; +?> +--EXPECT-- +Done diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index da09511a0deb1..ab85be7ca09aa 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -13,30 +13,6 @@ AC_DEFUN([AC_FPM_STDLIBS], AC_SEARCH_LIBS(inet_addr, nsl) ]) -AC_DEFUN([AC_FPM_PRCTL], -[ - AC_MSG_CHECKING([for prctl]) - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[prctl(0, 0, 0, 0, 0);]])], [ - AC_DEFINE([HAVE_PRCTL], 1, [do we have prctl?]) - AC_MSG_RESULT([yes]) - ], [ - AC_MSG_RESULT([no]) - ]) -]) - -AC_DEFUN([AC_FPM_PROCCTL], -[ - AC_MSG_CHECKING([for procctl]) - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[procctl(0, 0, 0, 0);]])], [ - AC_DEFINE([HAVE_PROCCTL], 1, [do we have procctl?]) - AC_MSG_RESULT([yes]) - ], [ - AC_MSG_RESULT([no]) - ]) -]) - AC_DEFUN([AC_FPM_SETPFLAGS], [ AC_MSG_CHECKING([for setpflags]) @@ -530,8 +506,6 @@ if test "$PHP_FPM" != "no"; then AC_MSG_RESULT($PHP_FPM) AC_FPM_STDLIBS - AC_FPM_PRCTL - AC_FPM_PROCCTL AC_FPM_SETPFLAGS AC_FPM_CLOCK AC_FPM_TRACE diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 2208bbd47b23b..365c378438739 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -74,10 +74,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include "lsapilib.h" -#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) +#ifdef HAVE_PRCTL #include #endif @@ -381,7 +382,7 @@ static void lsapi_enable_core_dump(void) #endif -#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) +#ifdef HAVE_PRCTL if (prctl(PR_SET_DUMPABLE, s_enable_core_dump,0,0,0) == -1) perror( "prctl: Failed to set dumpable, " "core dump may not be available!");