diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-08 04:59:11 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-08 04:59:11 +0100 |
commit | 830ea35484cecb8b4cdbe0f30cc5d573ff0e3411 (patch) | |
tree | 9057122598e964984f9bda62a75d7cb746cd602f | |
parent | 02affb4afd4a71b0c1ca6286f9b0f6bf3b10e0a1 (diff) | |
download | busybox-w32-830ea35484cecb8b4cdbe0f30cc5d573ff0e3411.tar.gz busybox-w32-830ea35484cecb8b4cdbe0f30cc5d573ff0e3411.tar.bz2 busybox-w32-830ea35484cecb8b4cdbe0f30cc5d573ff0e3411.zip |
hush: make "wait %1" less likely to play with signal mask
Was playing with "sleep 3 | exit 3 & wait %1" and noticed that often
SIGCHLD arrives even before I get to signal masking. Can avoid it in this
case.
function old new delta
wait_for_child_or_signal 228 265 +37
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/shell/hush.c b/shell/hush.c index ddbf2f7d8..5e51adfdc 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -8146,11 +8146,11 @@ static void install_fatal_sighandlers(void) | |||
8146 | 8146 | ||
8147 | /* We will restore tty pgrp on these signals */ | 8147 | /* We will restore tty pgrp on these signals */ |
8148 | mask = 0 | 8148 | mask = 0 |
8149 | + (1 << SIGILL ) * HUSH_DEBUG | 8149 | /*+ (1 << SIGILL ) * HUSH_DEBUG*/ |
8150 | + (1 << SIGFPE ) * HUSH_DEBUG | 8150 | /*+ (1 << SIGFPE ) * HUSH_DEBUG*/ |
8151 | + (1 << SIGBUS ) * HUSH_DEBUG | 8151 | + (1 << SIGBUS ) * HUSH_DEBUG |
8152 | + (1 << SIGSEGV) * HUSH_DEBUG | 8152 | + (1 << SIGSEGV) * HUSH_DEBUG |
8153 | + (1 << SIGTRAP) * HUSH_DEBUG | 8153 | /*+ (1 << SIGTRAP) * HUSH_DEBUG*/ |
8154 | + (1 << SIGABRT) | 8154 | + (1 << SIGABRT) |
8155 | /* bash 3.2 seems to handle these just like 'fatal' ones */ | 8155 | /* bash 3.2 seems to handle these just like 'fatal' ones */ |
8156 | + (1 << SIGPIPE) | 8156 | + (1 << SIGPIPE) |
@@ -9518,6 +9518,9 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid | |||
9518 | int sig; | 9518 | int sig; |
9519 | sigset_t oldset; | 9519 | sigset_t oldset; |
9520 | 9520 | ||
9521 | if (!sigisemptyset(&G.pending_set)) | ||
9522 | goto check_sig; | ||
9523 | |||
9521 | /* waitpid is not interruptible by SA_RESTARTed | 9524 | /* waitpid is not interruptible by SA_RESTARTed |
9522 | * signals which we use. Thus, this ugly dance: | 9525 | * signals which we use. Thus, this ugly dance: |
9523 | */ | 9526 | */ |
@@ -9532,7 +9535,6 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid | |||
9532 | 9535 | ||
9533 | if (!sigisemptyset(&G.pending_set)) { | 9536 | if (!sigisemptyset(&G.pending_set)) { |
9534 | /* Crap! we raced with some signal! */ | 9537 | /* Crap! we raced with some signal! */ |
9535 | // sig = 0; | ||
9536 | goto restore; | 9538 | goto restore; |
9537 | } | 9539 | } |
9538 | 9540 | ||
@@ -9567,13 +9569,10 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid | |||
9567 | sigsuspend(&oldset); | 9569 | sigsuspend(&oldset); |
9568 | restore: | 9570 | restore: |
9569 | sigprocmask(SIG_SETMASK, &oldset, NULL); | 9571 | sigprocmask(SIG_SETMASK, &oldset, NULL); |
9570 | 9572 | check_sig: | |
9571 | /* So, did we get a signal? */ | 9573 | /* So, did we get a signal? */ |
9572 | //if (sig > 0) | ||
9573 | // raise(sig); /* run handler */ | ||
9574 | sig = check_and_run_traps(); | 9574 | sig = check_and_run_traps(); |
9575 | if (sig /*&& sig != SIGCHLD - always true */) { | 9575 | if (sig /*&& sig != SIGCHLD - always true */) { |
9576 | /* see note 2 */ | ||
9577 | ret = 128 + sig; | 9576 | ret = 128 + sig; |
9578 | break; | 9577 | break; |
9579 | } | 9578 | } |