aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-08-04 14:28:16 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-08-04 14:28:16 +0200
commit49e6bf2db92d896a71d08eb364069ba50fa82781 (patch)
treeb0940fde4d99a73e1a27c7ad0b610fe7e3f1be0c /shell
parent3346b4afc5c81d53eae4e7fc7e12ebd6fa573a4e (diff)
downloadbusybox-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.c27
-rw-r--r--shell/hush.c7
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
13547static void 13551/* Don't inline: conserve stack of caller from having our locals too */
13552static NOINLINE void
13548init(void) 13553init(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);