MDL-87079 core: Call existing pcntl handlers

Whilst `register_shutdown_function` works as a queue, `pcntl_signal`
does not.

To preserve the behaviour of existing signal handlers, as are typically
found in CLI wrappers like PHPUnit and Behat, we should store any
existing handler
This commit is contained in:
Andrew Nicols
2025-11-05 08:51:40 +08:00
parent 543bf96cb7
commit b06f52ee0b
2 changed files with 24 additions and 2 deletions
@@ -0,0 +1,5 @@
issueNumber: MDL-87079
notes:
core:
- message: When responding to pcntl signals, call existing signal handlers.
type: fixed
+19 -2
View File
@@ -39,6 +39,9 @@ class core_shutdown_manager {
/** @var bool is this manager already registered? */
protected static $registered = false;
/** @var array A list of pcntl handlers */
protected static array $pcntlhandlers = [];
/**
* Register self as main shutdown handler.
*
@@ -62,8 +65,18 @@ class core_shutdown_manager {
pcntl_async_signals(true);
}
if (function_exists('pcntl_signal')) {
pcntl_signal(SIGINT, ['core_shutdown_manager', 'signal_handler']);
pcntl_signal(SIGTERM, ['core_shutdown_manager', 'signal_handler']);
$signals = [SIGINT, SIGTERM];
foreach ($signals as $signal) {
if (function_exists('pcntl_signal_get_handler')) {
$handler = pcntl_signal_get_handler($signal);
if (is_callable($handler)) {
// We can restore the original handler later if needed.
self::$pcntlhandlers[$signal] = $handler;
}
}
pcntl_signal($signal, ['core_shutdown_manager', 'signal_handler']);
}
}
}
}
@@ -111,6 +124,10 @@ class core_shutdown_manager {
error_log('Exception ignored in signal function ' . get_callable_name($callback) . ': ' . $e->getMessage());
}
}
if (array_key_exists($signo, self::$pcntlhandlers)) {
$handler = self::$pcntlhandlers[$signo];
$handler($signo);
}
if ($shouldexit) {
exit ($exitcode);