diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-04 14:28:16 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-04 14:28:16 +0200 |
commit | 49e6bf2db92d896a71d08eb364069ba50fa82781 (patch) | |
tree | b0940fde4d99a73e1a27c7ad0b610fe7e3f1be0c /shell | |
parent | 3346b4afc5c81d53eae4e7fc7e12ebd6fa573a4e (diff) | |
download | busybox-w32-49e6bf2db92d896a71d08eb364069ba50fa82781.tar.gz busybox-w32-49e6bf2db92d896a71d08eb364069ba50fa82781.tar.bz2 busybox-w32-49e6bf2db92d896a71d08eb364069ba50fa82781.zip |
sheel: improve comments on signal handling
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 27 | ||||
-rw-r--r-- | shell/hush.c | 7 |
2 files changed, 23 insertions, 11 deletions
diff --git a/shell/ash.c b/shell/ash.c index 8c9f4adc6..ca9926b54 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -3536,9 +3536,12 @@ setsignal(int signo) | |||
3536 | #endif | 3536 | #endif |
3537 | } | 3537 | } |
3538 | } | 3538 | } |
3539 | //TODO: if !rootshell, we reset SIGQUIT to DFL, | 3539 | /* if !rootshell, we reset SIGQUIT to DFL, |
3540 | //whereas we have to restore it to what shell got on entry | 3540 | * whereas we have to restore it to what shell got on entry. |
3541 | //from the parent. See comment above | 3541 | * This is handled by the fact that if signal was IGNored on entry, |
3542 | * then cur_act is S_HARD_IGN and we never change its sigaction | ||
3543 | * (see code below). | ||
3544 | */ | ||
3542 | 3545 | ||
3543 | if (signo == SIGCHLD) | 3546 | if (signo == SIGCHLD) |
3544 | new_act = S_CATCH; | 3547 | new_act = S_CATCH; |
@@ -3566,6 +3569,8 @@ setsignal(int signo) | |||
3566 | if (cur_act == S_HARD_IGN || cur_act == new_act) | 3569 | if (cur_act == S_HARD_IGN || cur_act == new_act) |
3567 | return; | 3570 | return; |
3568 | 3571 | ||
3572 | *t = new_act; | ||
3573 | |||
3569 | act.sa_handler = SIG_DFL; | 3574 | act.sa_handler = SIG_DFL; |
3570 | switch (new_act) { | 3575 | switch (new_act) { |
3571 | case S_CATCH: | 3576 | case S_CATCH: |
@@ -3575,16 +3580,13 @@ setsignal(int signo) | |||
3575 | act.sa_handler = SIG_IGN; | 3580 | act.sa_handler = SIG_IGN; |
3576 | break; | 3581 | break; |
3577 | } | 3582 | } |
3578 | |||
3579 | /* flags and mask matter only if !DFL and !IGN, but we do it | 3583 | /* flags and mask matter only if !DFL and !IGN, but we do it |
3580 | * for all cases for more deterministic behavior: | 3584 | * for all cases for more deterministic behavior: |
3581 | */ | 3585 | */ |
3582 | act.sa_flags = 0; | 3586 | act.sa_flags = 0; //TODO: why not SA_RESTART? |
3583 | sigfillset(&act.sa_mask); | 3587 | sigfillset(&act.sa_mask); |
3584 | 3588 | ||
3585 | sigaction_set(signo, &act); | 3589 | sigaction_set(signo, &act); |
3586 | |||
3587 | *t = new_act; | ||
3588 | } | 3590 | } |
3589 | 3591 | ||
3590 | /* mode flags for set_curjob */ | 3592 | /* mode flags for set_curjob */ |
@@ -13429,7 +13431,9 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13429 | INT_ON; | 13431 | INT_ON; |
13430 | 13432 | ||
13431 | if ((uintptr_t)r == 1 && errno == EINTR) { | 13433 | if ((uintptr_t)r == 1 && errno == EINTR) { |
13432 | /* to get SIGCHLD: sleep 1 & read x; echo $x */ | 13434 | /* To get SIGCHLD: sleep 1 & read x; echo $x |
13435 | * Correct behavior is to not exit "read" | ||
13436 | */ | ||
13433 | if (pending_sig == 0) | 13437 | if (pending_sig == 0) |
13434 | goto again; | 13438 | goto again; |
13435 | } | 13439 | } |
@@ -13544,13 +13548,14 @@ exitshell(void) | |||
13544 | /* NOTREACHED */ | 13548 | /* NOTREACHED */ |
13545 | } | 13549 | } |
13546 | 13550 | ||
13547 | static void | 13551 | /* Don't inline: conserve stack of caller from having our locals too */ |
13552 | static NOINLINE void | ||
13548 | init(void) | 13553 | init(void) |
13549 | { | 13554 | { |
13550 | /* we will never free this */ | 13555 | /* we will never free this */ |
13551 | basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ); | 13556 | basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ); |
13552 | 13557 | ||
13553 | sigmode[SIGCHLD - 1] = S_DFL; | 13558 | sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */ |
13554 | setsignal(SIGCHLD); | 13559 | setsignal(SIGCHLD); |
13555 | 13560 | ||
13556 | /* bash re-enables SIGHUP which is SIG_IGNed on entry. | 13561 | /* bash re-enables SIGHUP which is SIG_IGNed on entry. |
@@ -13561,7 +13566,6 @@ init(void) | |||
13561 | { | 13566 | { |
13562 | char **envp; | 13567 | char **envp; |
13563 | const char *p; | 13568 | const char *p; |
13564 | struct stat st1, st2; | ||
13565 | 13569 | ||
13566 | initvar(); | 13570 | initvar(); |
13567 | for (envp = environ; envp && *envp; envp++) { | 13571 | for (envp = environ; envp && *envp; envp++) { |
@@ -13587,6 +13591,7 @@ init(void) | |||
13587 | #endif | 13591 | #endif |
13588 | p = lookupvar("PWD"); | 13592 | p = lookupvar("PWD"); |
13589 | if (p) { | 13593 | if (p) { |
13594 | struct stat st1, st2; | ||
13590 | if (p[0] != '/' || stat(p, &st1) || stat(".", &st2) | 13595 | if (p[0] != '/' || stat(p, &st1) || stat(".", &st2) |
13591 | || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino | 13596 | || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino |
13592 | ) { | 13597 | ) { |
diff --git a/shell/hush.c b/shell/hush.c index b04f793f1..bb80f422c 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1979,6 +1979,9 @@ static int check_and_run_traps(void) | |||
1979 | break; | 1979 | break; |
1980 | #if ENABLE_HUSH_JOB | 1980 | #if ENABLE_HUSH_JOB |
1981 | case SIGHUP: { | 1981 | case SIGHUP: { |
1982 | //TODO: why are we doing this? ash and dash don't do this, | ||
1983 | //they have no handler for SIGHUP at all, | ||
1984 | //they rely on kernel to send SIGHUP+SIGCONT to orphaned process groups | ||
1982 | struct pipe *job; | 1985 | struct pipe *job; |
1983 | debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig); | 1986 | debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig); |
1984 | /* bash is observed to signal whole process groups, | 1987 | /* bash is observed to signal whole process groups, |
@@ -8646,6 +8649,10 @@ static void install_sighandlers(unsigned mask) | |||
8646 | */ | 8649 | */ |
8647 | if (sig == SIGCHLD) | 8650 | if (sig == SIGCHLD) |
8648 | continue; | 8651 | continue; |
8652 | /* bash re-enables SIGHUP which is SIG_IGNed on entry. | ||
8653 | * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$" | ||
8654 | */ | ||
8655 | //if (sig == SIGHUP) continue; - TODO? | ||
8649 | if (old_handler == SIG_IGN) { | 8656 | if (old_handler == SIG_IGN) { |
8650 | /* oops... restore back to IGN, and record this fact */ | 8657 | /* oops... restore back to IGN, and record this fact */ |
8651 | install_sighandler(sig, old_handler); | 8658 | install_sighandler(sig, old_handler); |