ash,hush: add comment about masked SIGCHLD, handle SIG_IGNed SIGHUP as in bash
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
47eb979404
commit
23bc562a05
26
shell/ash.c
26
shell/ash.c
@ -4307,8 +4307,19 @@ wait_block_or_sig(int *status)
|
|||||||
#if 1
|
#if 1
|
||||||
sigfillset(&mask);
|
sigfillset(&mask);
|
||||||
sigprocmask2(SIG_SETMASK, &mask); /* mask is updated */
|
sigprocmask2(SIG_SETMASK, &mask); /* mask is updated */
|
||||||
while (!got_sigchld && !pending_sig)
|
while (!got_sigchld && !pending_sig) {
|
||||||
sigsuspend(&mask);
|
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);
|
sigprocmask(SIG_SETMASK, &mask, NULL);
|
||||||
#else /* unsafe: a signal can set pending_sig after check, but before pause() */
|
#else /* unsafe: a signal can set pending_sig after check, but before pause() */
|
||||||
while (!got_sigchld && !pending_sig)
|
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 */
|
sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */
|
||||||
setsignal(SIGCHLD);
|
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;
|
char **envp;
|
||||||
const char *p;
|
const char *p;
|
||||||
@ -14512,6 +14518,14 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
state4: /* XXX ??? - why isn't this before the "if" statement */
|
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);
|
cmdloop(1);
|
||||||
}
|
}
|
||||||
#if PROFILE
|
#if PROFILE
|
||||||
|
20
shell/hush.c
20
shell/hush.c
@ -9775,10 +9775,14 @@ static void install_sighandlers(unsigned mask)
|
|||||||
*/
|
*/
|
||||||
if (sig == SIGCHLD)
|
if (sig == SIGCHLD)
|
||||||
continue;
|
continue;
|
||||||
/* bash re-enables SIGHUP which is SIG_IGNed on entry.
|
/* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry.
|
||||||
* Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
|
* 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) {
|
if (old_handler == SIG_IGN) {
|
||||||
/* oops... restore back to IGN, and record this fact */
|
/* oops... restore back to IGN, and record this fact */
|
||||||
install_sighandler(sig, old_handler);
|
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! */
|
/* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */
|
||||||
/* Note: sigsuspend invokes signal handler */
|
/* Note: sigsuspend invokes signal handler */
|
||||||
sigsuspend(&oldset);
|
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:
|
restore:
|
||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
check_sig:
|
check_sig:
|
||||||
|
Loading…
Reference in New Issue
Block a user