From 9130c48be81858b83b63427c057af0318a56d382 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Fri, 19 Sep 2025 06:55:05 +0000 Subject: [PATCH] Limiting scope of signal handling based on environment - Do not handle Linux signals if the PCNTL extension is unavailable. Artisan commands can still function without this extension - they just simply cannot handle termination signals. - Prevent multiple registrations of the Windows signal handler if the method is called multiple times. - Remove specific checks for Windows signals - the handler only accepts two types of signals (CTRL+C or CTRL+BREAK) and both are termination signals. --- src/Console/Traits/HandlesCleanup.php | 31 ++++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/Console/Traits/HandlesCleanup.php b/src/Console/Traits/HandlesCleanup.php index d322f737a..4dad8f491 100644 --- a/src/Console/Traits/HandlesCleanup.php +++ b/src/Console/Traits/HandlesCleanup.php @@ -1,4 +1,6 @@ -windowsSignalHandlerRegistered) { + if (sapi_windows_set_ctrl_handler([$this, 'handleWindowsSignal'], true)) { + $this->windowsSignalHandlerRegistered = true; + } } // Handle Unix-like OS - } else { + } elseif (function_exists('pcntl_signal')) { $signals = [SIGINT, SIGTERM, SIGQUIT]; } } @@ -51,7 +58,7 @@ public function handleSignal(int $signal, /* int|false $previousExitCode = 0 */) } // Exit cleanly at this point if this was a user termination - if (in_array($signal, [SIGINT, SIGQUIT])) { + if (function_exists('pcntl_signal') && in_array($signal, [SIGINT, SIGQUIT])) { return 0; } @@ -64,16 +71,14 @@ public function handleSignal(int $signal, /* int|false $previousExitCode = 0 */) public function handleWindowsSignal(int $event): void { // Remove the handler - sapi_windows_set_ctrl_handler([$this, 'handleWindowsSignal'], false); + if ($this->windowsSignalHandlerRegistered) { + if (sapi_windows_set_ctrl_handler([$this, 'handleWindowsSignal'], false)) { + $this->windowsSignalHandlerRegistered = false; + } + } // Handle the signal - if ( - method_exists($this, 'handleCleanup') - && ( - $event === PHP_WINDOWS_EVENT_CTRL_C - || $event === PHP_WINDOWS_EVENT_CTRL_BREAK - ) - ) { + if (method_exists($this, 'handleCleanup')) { $this->handleCleanup(); // Exit cleanly at this point if this was a user termination