ash,hush: add comment about masked SIGCHLD, handle SIG_IGNed SIGHUP as in bash
No binary (build failed)
—
(log yok)
| @@ -4307,8 +4307,19 @@ wait_block_or_sig(int *status) | |
| #if 1 | |
| sigfillset(&mask); | |
| sigprocmask2(SIG_SETMASK, &mask); /* mask is updated */ | |
| - | while (!got_sigchld && !pending_sig) |
| + | while (!got_sigchld && !pending_sig) { |
| sigsuspend(&mask); | |
| + | /* ^^^ add "sigdelset(&mask, SIGCHLD);" before sigsuspend |
| + | * to make sure SIGCHLD is not masked off? |
| + | * It was reported that this: |
| + | * fn() { : | return; } |
| + | * shopt -s lastpipe |
| + | * fn |
| + | * exec ash SCRIPT |
| + | * under bash 4.4.23 runs SCRIPT with SIGCHLD masked, |
| + | * making "wait" commands in SCRIPT block forever. |
| + | */ |
| + | } |
| sigprocmask(SIG_SETMASK, &mask, NULL); | |
| #else /* unsafe: a signal can set pending_sig after check, but before pause() */ | |
| while (!got_sigchld && !pending_sig) | |
| @@ -14170,11 +14181,6 @@ init(void) | |
| sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */ | |
| setsignal(SIGCHLD); | |
| - | /* bash re-enables SIGHUP which is SIG_IGNed on entry. |
| - | * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$" |
| - | */ |
| - | signal(SIGHUP, SIG_DFL); |
| - | |
| { | |
| char **envp; | |
| const char *p; | |
| @@ -14512,6 +14518,14 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| #endif | |
| state4: /* XXX ??? - why isn't this before the "if" statement */ | |
| + | |
| + | /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry. |
| + | * Try: |
| + | * trap '' hup; bash; echo RET # type "kill -hup $$", see SIGHUP having effect |
| + | * trap '' hup; bash -c 'kill -hup $$; echo ALIVE' # here SIGHUP is SIG_IGNed |
| + | */ |
| + | signal(SIGHUP, SIG_DFL); |
| + | |
| cmdloop(1); | |
| } | |
| #if PROFILE | |
| @@ -9775,10 +9775,14 @@ static void install_sighandlers(unsigned mask) | |
| */ | |
| if (sig == SIGCHLD) | |
| continue; | |
| - | /* bash re-enables SIGHUP which is SIG_IGNed on entry. |
| - | * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$" |
| + | /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry. |
| + | * Try: |
| + | * trap '' hup; bash; echo RET # type "kill -hup $$", see SIGHUP having effect |
| + | * trap '' hup; bash -c 'kill -hup $$; echo ALIVE' # here SIGHUP is SIG_IGNed |
| */ | |
| - | //if (sig == SIGHUP) continue; - TODO? |
| + | if (sig == SIGHUP && G_interactive_fd) |
| + | continue; |
| + | /* Unless one of the above signals, is it SIG_IGN? */ |
| if (old_handler == SIG_IGN) { | |
| /* oops... restore back to IGN, and record this fact */ | |
| install_sighandler(sig, old_handler); | |
| @@ -11554,6 +11558,16 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid | |
| /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */ | |
| /* Note: sigsuspend invokes signal handler */ | |
| sigsuspend(&oldset); | |
| + | /* ^^^ add "sigdelset(&oldset, SIGCHLD)" before sigsuspend |
| + | * to make sure SIGCHLD is not masked off? |
| + | * It was reported that this: |
| + | * fn() { : | return; } |
| + | * shopt -s lastpipe |
| + | * fn |
| + | * exec hush SCRIPT |
| + | * under bash 4.4.23 runs SCRIPT with SIGCHLD masked, |
| + | * making "wait" commands in SCRIPT block forever. |
| + | */ |
| restore: | |
| sigprocmask(SIG_SETMASK, &oldset, NULL); | |
| check_sig: | |