mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
Fixed bug #73783
Bug #73783 raises an issue with signal handling when using SIG_IGN. With PHP7.1 ZEND_SIGNALS is defaulted to on, which will for all signals set the handler as zend_signal_handler_defer. This is problematic for syscalls like sleep(), which will only return when the requisite number of seconds have elapsed, or, a non-ignored signal is raised. In this case we want to SIG_IGN SIGCHLD, however, SIG_IGN is only stored in the SIGG(handlers) array, and the actual system level handler is defined. This prevents proper signal ignoring when requeted.
This commit is contained in:
parent
7746ed9d5f
commit
b09c2f899e
2
NEWS
2
NEWS
@ -11,6 +11,8 @@ PHP NEWS
|
||||
. Fixed bug #73727 (ZEND_MM_BITSET_LEN is "undefined symbol" in
|
||||
zend_bitset.h). (Nikita)
|
||||
. Fixed bug #73753 (unserialized array pointer not advancing). (David Walker)
|
||||
. Fixed bug #73783 (SIG_IGN doesn't work when Zend Signals is enabled).
|
||||
(David Walker)
|
||||
|
||||
- CLI:
|
||||
. Fixed bug #72555 (CLI output(japanese) on Windows). (Anatol)
|
||||
|
@ -198,7 +198,7 @@ static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else if (p_sig.handler != SIG_IGN) { /* ignore SIG_IGN */
|
||||
} else {
|
||||
if (p_sig.flags & SA_SIGINFO) {
|
||||
if (p_sig.flags & SA_RESETHAND) {
|
||||
SIGG(handlers)[signo-1].flags = 0;
|
||||
@ -234,9 +234,13 @@ ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigac
|
||||
}
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_flags = SA_SIGINFO | (act->sa_flags & SA_FLAGS_MASK);
|
||||
sa.sa_sigaction = zend_signal_handler_defer;
|
||||
sa.sa_mask = global_sigmask;
|
||||
if (SIGG(handlers)[signo-1].handler == (void *) SIG_IGN) {
|
||||
sa.sa_sigaction = (void *) SIG_IGN;
|
||||
} else {
|
||||
sa.sa_flags = SA_SIGINFO | (act->sa_flags & SA_FLAGS_MASK);
|
||||
sa.sa_sigaction = zend_signal_handler_defer;
|
||||
sa.sa_mask = global_sigmask;
|
||||
}
|
||||
|
||||
if (sigaction(signo, &sa, NULL) < 0) {
|
||||
zend_error_noreturn(E_ERROR, "Error installing signal handler for %d", signo);
|
||||
|
28
ext/pcntl/tests/bug73783.phpt
Normal file
28
ext/pcntl/tests/bug73783.phpt
Normal file
@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #73783: (SIG_IGN needs to be set to prevent syscals from returning early)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pcntl')) die('skip pcntl extension not available');
|
||||
elseif (!extension_loaded('posix')) die('skip posix extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
pcntl_signal(SIGCHLD, SIG_IGN);
|
||||
|
||||
switch(pcntl_fork()) {
|
||||
case 0:
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
|
||||
$before = microtime(true);
|
||||
sleep(1);
|
||||
|
||||
if (microtime(true) - $before >= 0.8) {
|
||||
echo "working\n";
|
||||
} else {
|
||||
echo "failed\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
working
|
Loading…
Reference in New Issue
Block a user