From 02cd7f033dae55b9c4903c9a28b7927f94709a35 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Tue, 17 Nov 2015 13:39:34 +0000 Subject: Invoke notify scripts with the default signal disposition It is reasonable for notify scripts to expect to be invoked with the standard signal disposition, so when first setting up signal dispositions, remember the original state so it can be restored before the notify scripts are exec'd. Signed-off-by: Quentin Armitage (cherry picked from commit 2e65a87ff63c3e23659c05c7b844f1a277664b7f) --- lib/notify.c | 2 +- lib/signals.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++----------- lib/signals.h | 1 + 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/lib/notify.c b/lib/notify.c index 80cc91e..f71efa9 100644 --- a/lib/notify.c +++ b/lib/notify.c @@ -76,7 +76,7 @@ notify_exec(char *cmd) if (pid) return 0; - signal_handler_destroy(); + signal_handler_notify(); closeall(0); open("/dev/null", O_RDWR); diff --git a/lib/signals.c b/lib/signals.c index 8372ec9..fb22b14 100644 --- a/lib/signals.c +++ b/lib/signals.c @@ -50,6 +50,11 @@ void *signal_SIGUSR2_v; static int signal_pipe[2] = { -1, -1 }; +/* Remember our initial signal disposition */ +int initialised_default_signals; +sigset_t ign_sig; +sigset_t dfl_sig; + /* Local signal test */ /* Currently unused int @@ -167,7 +172,7 @@ signal_handler_init(void) { sigset_t sset; int sig; - struct sigaction act; + struct sigaction act, oact; int n = pipe(signal_pipe); assert(!n); @@ -181,20 +186,40 @@ signal_handler_init(void) signal_SIGUSR1_handler = NULL; signal_SIGUSR2_handler = NULL; - /* Ignore all signals by default (except essential ones) */ - sigfillset(&sset); - sigdelset(&sset, SIGILL); - sigdelset(&sset, SIGFPE); - sigdelset(&sset, SIGSEGV); - sigdelset(&sset, SIGBUS); - sigdelset(&sset, SIGKILL); - sigdelset(&sset, SIGSTOP); - act.sa_handler = SIG_IGN; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - for (sig = 1; sig <= SIGRTMAX; sig++) { - if (sigismember(&sset, sig)) - sigaction(sig, &act, NULL); + if (!initialised_default_signals) { + /* Ignore all signals set to default (except essential ones) */ + sigfillset(&sset); + sigdelset(&sset, SIGILL); + sigdelset(&sset, SIGFPE); + sigdelset(&sset, SIGSEGV); + sigdelset(&sset, SIGBUS); + sigdelset(&sset, SIGKILL); + sigdelset(&sset, SIGSTOP); + + act.sa_handler = SIG_IGN; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + sigemptyset(&ign_sig); + sigemptyset(&dfl_sig); + + for (sig = 1; sig <= SIGRTMAX; sig++) { + if (sigismember(&sset, sig)){ + sigaction(sig, NULL, &oact); + + /* Remember the original disposition, and ignore + * any default action signals + */ + if ( oact.sa_handler == SIG_IGN) + sigaddset(&ign_sig, sig); + else if ( oact.sa_handler == SIG_DFL) { + sigaction(sig, &act, NULL); + sigaddset(&dfl_sig, sig); + } + } + } + + initialised_default_signals = 1; } } @@ -227,6 +252,34 @@ signal_handler_destroy(void) signal_pipe[0] = -1; } +/* Called prior to exec'ing a notify script. The script can reasonably + * expect to have the standard signal disposition */ +void +signal_handler_notify(void) +{ + struct sigaction ign, dfl; + int sig; + + ign.sa_handler = SIG_IGN; + ign.sa_flags = 0; + sigemptyset(&ign.sa_mask); + dfl.sa_handler = SIG_DFL; + dfl.sa_flags = 0; + sigemptyset(&dfl.sa_mask); + + for (sig = 1; sig <= SIGRTMAX; sig++) { + if (sigismember(&ign_sig, sig)) + sigaction(sig, &ign, NULL); + else if (sigismember(&dfl_sig, sig)) + sigaction(sig, &dfl, NULL); + } + + close(signal_pipe[1]); + close(signal_pipe[0]); + signal_pipe[1] = -1; + signal_pipe[0] = -1; +} + int signal_rfd(void) { diff --git a/lib/signals.h b/lib/signals.h index 8e28ee7..1a3f91d 100644 --- a/lib/signals.h +++ b/lib/signals.h @@ -31,6 +31,7 @@ extern void *signal_ignore(int signo); extern void signal_handler_init(void); extern void signal_handler_destroy(void); extern void signal_handler_reset(void); +extern void signal_handler_notify(void); extern void signal_run_callback(void); extern int signal_rfd(void); -- 1.7.12.1