diff --git a/src/CLI.php b/src/CLI.php index 16ffe4a..a4618ab 100644 --- a/src/CLI.php +++ b/src/CLI.php @@ -361,6 +361,52 @@ public static function spinner(int $frame = 0, bool $finalize = false) : void static::liveLine($frames[$frame % \count($frames)]); } + /** + * Register a handler for the given POSIX signal when pcntl is available. + * + * @param int $signal The signal number + * @param callable $handler The signal handler + * + * @return bool True if the handler was registered, false if pcntl is unavailable + */ + public static function onSignal(int $signal, callable $handler) : bool + { + if (!\function_exists('pcntl_signal')) { + return false; + } + return \pcntl_signal($signal, $handler, true); + } + + /** + * Register a cleanup handler for the interrupt signal (Ctrl+C) when available. + * + * @param callable $handler The signal handler + * + * @return bool True if the handler was registered + */ + public static function onSigint(callable $handler) : bool + { + if (!\defined('SIGINT')) { + return false; + } + return static::onSignal(\SIGINT, $handler); + } + + /** + * Restore the default handler for a POSIX signal when pcntl is available. + * + * @param int $signal The signal number + * + * @return bool True if the handler was restored + */ + public static function restoreSignal(int $signal) : bool + { + if (!\function_exists('pcntl_signal')) { + return false; + } + return \pcntl_signal($signal, \SIG_DFL); + } + /** * Performs audible beep alarms. * diff --git a/tests/CLITest.php b/tests/CLITest.php index 97678d7..61ee51b 100644 --- a/tests/CLITest.php +++ b/tests/CLITest.php @@ -266,4 +266,14 @@ public function testSpinner() : void self::assertStringContainsString('|', Stdout::getContents()); CLI::setAnsi(true); } + + public function testSignals() : void + { + $term = \defined('SIGTERM') ? \SIGTERM : 15; + self::assertIsBool(CLI::onSignal($term, static function () : void { + })); + self::assertIsBool(CLI::onSigint(static function () : void { + })); + self::assertIsBool(CLI::restoreSignal($term)); + } }