diff options
Diffstat (limited to 'Zend/zend_signal.c')
| -rw-r--r-- | Zend/zend_signal.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c index b12f30d31b..e067c518e8 100644 --- a/Zend/zend_signal.c +++ b/Zend/zend_signal.c @@ -48,7 +48,19 @@ #ifdef ZTS ZEND_API int zend_signal_globals_id; #else -zend_signal_globals_t zend_signal_globals; +ZEND_API zend_signal_globals_t zend_signal_globals; +#endif /* not ZTS */ + +#define SIGNAL_BEGIN_CRITICAL() \ + sigset_t oldmask; \ + zend_sigprocmask(SIG_BLOCK, &global_sigmask, &oldmask); +#define SIGNAL_END_CRITICAL() \ + zend_sigprocmask(SIG_SETMASK, &oldmask, NULL); + +#ifdef ZTS +# define zend_sigprocmask(signo, set, oldset) tsrm_sigmask((signo), (set), (oldset)) +#else +# define zend_sigprocmask(signo, set, oldset) sigprocmask((signo), (set), (oldset)) #endif static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context); @@ -165,7 +177,7 @@ ZEND_API void zend_signal_handler_unblock(void) static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context) { int errno_save = errno; - struct sigaction sa = {{0}}; + struct sigaction sa; sigset_t sigset; zend_signal_entry_t p_sig; #ifdef ZTS @@ -186,11 +198,19 @@ static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context) if (sigaction(signo, &sa, NULL) == 0) { /* throw away any blocked signals */ - sigprocmask(SIG_UNBLOCK, &sigset, NULL); - raise(signo); + zend_sigprocmask(SIG_UNBLOCK, &sigset, NULL); +#ifdef ZTS +# define RAISE_ERROR "raise() failed\n" + if (raise(signo) != 0) { + /* On some systems raise() fails with errno 3: No such process */ + kill(getpid(), signo); + } +#else + kill(getpid(), signo); +#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; @@ -209,7 +229,7 @@ static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context) * Register a signal handler that will be deferred in critical sections */ ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigaction *oldact) { - struct sigaction sa = {{0}}; + struct sigaction sa; sigset_t sigset; if (oldact != NULL) { @@ -225,9 +245,14 @@ ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigac SIGG(handlers)[signo-1].handler = (void *) act->sa_handler; } - sa.sa_flags = SA_SIGINFO | (act->sa_flags & SA_FLAGS_MASK); - sa.sa_sigaction = zend_signal_handler_defer; - sa.sa_mask = global_sigmask; + memset(&sa, 0, sizeof(sa)); + 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); @@ -247,8 +272,9 @@ ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigac * Register a signal handler that will be deferred in critical sections */ ZEND_API int zend_signal(int signo, void (*handler)(int)) { - struct sigaction sa = {{0}}; + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); sa.sa_flags = 0; sa.sa_handler = handler; sa.sa_mask = global_sigmask; @@ -263,7 +289,7 @@ ZEND_API int zend_signal(int signo, void (*handler)(int)) */ static int zend_signal_register(int signo, void (*handler)(int, siginfo_t*, void*)) { - struct sigaction sa = {{0}}; + struct sigaction sa; if (sigaction(signo, NULL, &sa) == 0) { if ((sa.sa_flags & SA_SIGINFO) && sa.sa_sigaction == handler) { @@ -294,7 +320,7 @@ static int zend_signal_register(int signo, void (*handler)(int, siginfo_t*, void * Install our signal handlers, per request */ void zend_signal_activate(void) { - int x; + size_t x; memcpy(&SIGG(handlers), &global_orig_handlers, sizeof(global_orig_handlers)); @@ -312,8 +338,9 @@ void zend_signal_deactivate(void) { if (SIGG(check)) { - int x; - struct sigaction sa = {{0}}; + size_t x; + struct sigaction sa; + if (SIGG(depth) != 0) { zend_error(E_CORE_WARNING, "zend_signal: shutdown with non-zero blocking depth (%d)", SIGG(depth)); } @@ -350,10 +377,10 @@ static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals) } /* }}} */ -void zend_signal_init() /* {{{ */ +void zend_signal_init(void) /* {{{ */ { int signo; - struct sigaction sa = {{0}}; + struct sigaction sa; /* Save previously registered signal handlers into orig_handlers */ memset(&global_orig_handlers, 0, sizeof(global_orig_handlers)); @@ -372,7 +399,7 @@ void zend_signal_init() /* {{{ */ /* {{{ zend_signal_startup * alloc zend signal globals */ -void zend_signal_startup() +void zend_signal_startup(void) { #ifdef ZTS |
