Subprocesses of async subshells don't inherit SIG_IGN
after trap INT
since bash-4.3-rc2
:
h. Fixed a bug that caused SIGINT and SIGQUIT to not be trappable in asynchronous subshell commands.
Before:
$ bash -c '(trap INT; sleep infinity) & wait'
$ ps -eHo pid,ppid,pgid,tty,stat,ignored,args
PID PPID PGID TT STAT IGNORED COMMAND
...
38886 16721 38886 pts/1 S+ 0000000000000004 ./bash -c (trap INT; sleep infinity) & wait
38887 38886 38886 pts/1 S+ 0000000000000004 ./bash -c (trap INT; sleep infinity) & wait
38888 38887 38886 pts/1 S+ 0000000000000006 sleep infinity
sleep
has SIGINT
set to SIG_IGN
. After SIGINT
the subshell and sleep
remain.
After:
$ bash -c '(trap INT; sleep infinity) & wait'
$ ps -eHo pid,ppid,pgid,tty,stat,ignored,args
PID PPID PGID TT STAT IGNORED COMMAND
...
38893 38818 38893 pts/5 S+ 0000000000000004 ./bash -c (trap INT; sleep infinity) & wait
38894 38893 38893 pts/5 S+ 0000000000000004 ./bash -c (trap INT; sleep infinity) & wait
38895 38894 38893 pts/5 S+ 0000000000000000 sleep infinity
sleep
has SIGINT
set to SIG_DFL
. After SIGINT
the subshell and sleep
exit.
And one can set arbitrary traps in async subshells:
Before:
$ bash -c '(trap "echo \$\$: INT; trap INT; kill -2 \$\$" INT; sleep infinity) & wait'
$ ps -eHo pid,ppid,pgid,tty,stat,ignored,args
PID PPID PGID TT STAT IGNORED COMMAND
...
38900 16721 38900 pts/1 S+ 0000000000000004 ./bash -c (trap "echo \$\$: INT; trap INT; kill -2 \$\$"
38901 38900 38900 pts/1 S+ 0000000000000006 ./bash -c (trap "echo \$\$: INT; trap INT; kill -2 \$\
38902 38901 38900 pts/1 S+ 0000000000000006 sleep infinity
The subshell and sleep
has SIGINT
set to SIG_IGN
. After SIGINT
they remain.
After:
$ bash -c '(trap "echo \$\$: INT; trap INT; kill -2 \$\$" INT; sleep infinity) & wait'
$ ps -eHo pid,ppid,pgid,tty,stat,ignored,args
PID PPID PGID TT STAT IGNORED COMMAND
...
38907 38818 38907 pts/5 S+ 0000000000000004 ./bash -c (trap "echo \$\$: INT; trap INT; kill -2 \$\$"
38908 38907 38907 pts/5 S+ 0000000000000004 ./bash -c (trap "echo \$\$: INT; trap INT; kill -2 \$\
38909 38908 38907 pts/5 S+ 0000000000000000 sleep infinity
The subshell and sleep
has SIGINT
set to SIG_DFL
. After SIGINT
they exit. And the trap produces the output.
commit (4.3-rc2
)
commit (4.3
)
issue
+execute_cmd.c
+ - setup_async_signals: make sure we get the original dispositions for
+ SIGINT and SIGQUIT before starting the subshell, and don't call
+ set_signal_ignored because that sets original_signals[sig]. If we
+ don't, subsequent attempts to reset handling using trap will fail
+ because it thinks the original dispositions were SIG_IGN. Posix
+ interpretation 751 (http://austingroupbugs.net/view.php?id=751)
https://git.savannah.gnu.org/cgit/bash.git/tree/CWRU/changelog?h=bash-4.3-rc2&id=b6e23235f28b1c85e18e9a2b7ba8c6b6c46aecbc#n5554
https://git.savannah.gnu.org/cgit/bash.git/tree/CWRU/changelog?h=bash-4.3&id=ac50fbac377e32b98d2de396f016ea81e8ee9961#n5554
@@ -4794,10 +4809,15 @@ setup_async_signals ()
if (job_control == 0)
#endif
{
+ /* Make sure we get the original signal dispositions now so we don't
+ confuse the trap builtin later if the subshell tries to use it to
+ reset SIGINT/SIGQUIT. Don't call set_signal_ignored; that sets
+ the value of original_signals to SIG_IGN. Posix interpretation 751. */
+ get_original_signal (SIGINT);
set_signal_handler (SIGINT, SIG_IGN);
- set_signal_ignored (SIGINT);
+
+ get_original_signal (SIGQUIT);
set_signal_handler (SIGQUIT, SIG_IGN);
- set_signal_ignored (SIGQUIT);
}
}
https://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c?h=bash-4.3-rc2&id=b6e23235f28b1c85e18e9a2b7ba8c6b6c46aecbc#n4812
https://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c?h=bash-4.3&id=ac50fbac377e32b98d2de396f016ea81e8ee9961#n4824