aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c26
-rw-r--r--shell/hush.c20
2 files changed, 37 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c
index ff594050c..fea4b10a7 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -4307,8 +4307,19 @@ wait_block_or_sig(int *status)
4307#if 1 4307#if 1
4308 sigfillset(&mask); 4308 sigfillset(&mask);
4309 sigprocmask2(SIG_SETMASK, &mask); /* mask is updated */ 4309 sigprocmask2(SIG_SETMASK, &mask); /* mask is updated */
4310 while (!got_sigchld && !pending_sig) 4310 while (!got_sigchld && !pending_sig) {
4311 sigsuspend(&mask); 4311 sigsuspend(&mask);
4312 /* ^^^ add "sigdelset(&mask, SIGCHLD);" before sigsuspend
4313 * to make sure SIGCHLD is not masked off?
4314 * It was reported that this:
4315 * fn() { : | return; }
4316 * shopt -s lastpipe
4317 * fn
4318 * exec ash SCRIPT
4319 * under bash 4.4.23 runs SCRIPT with SIGCHLD masked,
4320 * making "wait" commands in SCRIPT block forever.
4321 */
4322 }
4312 sigprocmask(SIG_SETMASK, &mask, NULL); 4323 sigprocmask(SIG_SETMASK, &mask, NULL);
4313#else /* unsafe: a signal can set pending_sig after check, but before pause() */ 4324#else /* unsafe: a signal can set pending_sig after check, but before pause() */
4314 while (!got_sigchld && !pending_sig) 4325 while (!got_sigchld && !pending_sig)
@@ -14170,11 +14181,6 @@ init(void)
14170 sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */ 14181 sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */
14171 setsignal(SIGCHLD); 14182 setsignal(SIGCHLD);
14172 14183
14173 /* bash re-enables SIGHUP which is SIG_IGNed on entry.
14174 * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
14175 */
14176 signal(SIGHUP, SIG_DFL);
14177
14178 { 14184 {
14179 char **envp; 14185 char **envp;
14180 const char *p; 14186 const char *p;
@@ -14512,6 +14518,14 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
14512 } 14518 }
14513#endif 14519#endif
14514 state4: /* XXX ??? - why isn't this before the "if" statement */ 14520 state4: /* XXX ??? - why isn't this before the "if" statement */
14521
14522 /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry.
14523 * Try:
14524 * trap '' hup; bash; echo RET # type "kill -hup $$", see SIGHUP having effect
14525 * trap '' hup; bash -c 'kill -hup $$; echo ALIVE' # here SIGHUP is SIG_IGNed
14526 */
14527 signal(SIGHUP, SIG_DFL);
14528
14515 cmdloop(1); 14529 cmdloop(1);
14516 } 14530 }
14517#if PROFILE 14531#if PROFILE
diff --git a/shell/hush.c b/shell/hush.c
index 6e44d4e11..bced388bf 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -9775,10 +9775,14 @@ static void install_sighandlers(unsigned mask)
9775 */ 9775 */
9776 if (sig == SIGCHLD) 9776 if (sig == SIGCHLD)
9777 continue; 9777 continue;
9778 /* bash re-enables SIGHUP which is SIG_IGNed on entry. 9778 /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry.
9779 * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$" 9779 * Try:
9780 * trap '' hup; bash; echo RET # type "kill -hup $$", see SIGHUP having effect
9781 * trap '' hup; bash -c 'kill -hup $$; echo ALIVE' # here SIGHUP is SIG_IGNed
9780 */ 9782 */
9781 //if (sig == SIGHUP) continue; - TODO? 9783 if (sig == SIGHUP && G_interactive_fd)
9784 continue;
9785 /* Unless one of the above signals, is it SIG_IGN? */
9782 if (old_handler == SIG_IGN) { 9786 if (old_handler == SIG_IGN) {
9783 /* oops... restore back to IGN, and record this fact */ 9787 /* oops... restore back to IGN, and record this fact */
9784 install_sighandler(sig, old_handler); 9788 install_sighandler(sig, old_handler);
@@ -11554,6 +11558,16 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid
11554 /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */ 11558 /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */
11555 /* Note: sigsuspend invokes signal handler */ 11559 /* Note: sigsuspend invokes signal handler */
11556 sigsuspend(&oldset); 11560 sigsuspend(&oldset);
11561 /* ^^^ add "sigdelset(&oldset, SIGCHLD)" before sigsuspend
11562 * to make sure SIGCHLD is not masked off?
11563 * It was reported that this:
11564 * fn() { : | return; }
11565 * shopt -s lastpipe
11566 * fn
11567 * exec hush SCRIPT
11568 * under bash 4.4.23 runs SCRIPT with SIGCHLD masked,
11569 * making "wait" commands in SCRIPT block forever.
11570 */
11557 restore: 11571 restore:
11558 sigprocmask(SIG_SETMASK, &oldset, NULL); 11572 sigprocmask(SIG_SETMASK, &oldset, NULL);
11559 check_sig: 11573 check_sig: