See the new gist.
bash
allows to override SIGINT
in async subprocesses when job control is disabled since 4.3
:
$ bash -c 'sleep 10 & wait'
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
172495 13008 172495 S 0000000000380004 ./bash
172521 172495 172521 S+ 0000000000000004 ./bash -c sleep 10 & wait
172522 172521 172521 S+ 0000000000000006 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
172495 13008 172495 S 0000000000380004 ./bash
...
172522 1 172521 S 0000000000000006 sleep 10
$ bash -c '(trap - INT; sleep 10) & wait'
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
172495 13008 172495 S 0000000000380004 ./bash
172525 172495 172525 S+ 0000000000000004 ./bash -c (trap - INT; sleep 10) & wait
172526 172525 172525 S+ 0000000000000004 ./bash -c (trap - INT; sleep 10) & wait
172527 172526 172525 S+ 0000000000000000 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
172495 13008 172495 S 0000000000380004 ./bash
...
bash-4.3-rc2~
/bash-4.3~
:
$ bash -c '(trap - INT; sleep 10) & wait'
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
128543 13008 128543 S 0000000000380004 ./bash
128545 128543 128545 S+ 0000000000000004 ./bash -c (trap - INT; sleep 10) & wait
128546 128545 128545 S+ 0000000000000004 ./bash -c (trap - INT; sleep 10) & wait
128547 128546 128545 S+ 0000000000000006 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
128543 13008 128543 S 0000000000380004 ./bash
...
128546 1 128545 S 0000000000000004 ./bash -c (trap - INT; sleep 10) & wait
128547 128546 128545 S 0000000000000006 sleep 10
$ bash -c '(trap - INT; exec sleep 10) & wait'
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
128543 13008 128543 S 0000000000380004 ./bash
128550 128543 128550 S+ 0000000000000004 ./bash -c (trap - INT; exec sleep 10) & wait
128551 128550 128550 S+ 0000000000000006 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
128543 13008 128543 S 0000000000380004 ./bash
...
128551 1 128550 S 0000000000000006 sleep 10
$ set +m
$ (trap - INT; sleep 10) & wait
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
128543 13008 128543 S+ 0000000000380004 ./bash
128554 128543 128543 S+ 0000000000000004 ./bash
128555 128554 128543 S+ 0000000000000006 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
128543 13008 128543 S+ 0000000000380004 ./bash
128554 128543 128543 S+ 0000000000000004 ./bash
128555 128554 128543 S+ 0000000000000006 sleep 10
...
$ (trap - INT; exec sleep 10) & wait
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
128543 13008 128543 S+ 0000000000380004 ./bash
128558 128543 128543 S+ 0000000000000006 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
128543 13008 128543 S+ 0000000000380004 ./bash
128558 128543 128543 S+ 0000000000000006 sleep 10
...
bash-4.3-rc2
/bash-4.3
:
sleep
no longer ignores SIGINT
.
$ bash -c '(trap - INT; sleep 10) & wait'
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
139862 13008 139862 S 0000000000380004 ./bash
139873 139862 139873 S+ 0000000000000004 ./bash -c (trap - INT; sleep 10) & wait
139874 139873 139873 S+ 0000000000000004 ./bash -c (trap - INT; sleep 10) & wait
139875 139874 139873 S+ 0000000000000000 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
139862 13008 139862 S 0000000000380004 ./bash
...
$ bash -c '(trap - INT; exec sleep 10) & wait'
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
139862 13008 139862 S 0000000000380004 ./bash
139878 139862 139878 S+ 0000000000000004 ./bash -c (trap - INT; exec sleep 10) & wait
139879 139878 139878 S+ 0000000000000000 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
139862 13008 139862 S 0000000000380004 ./bash
...
$ set +m
$ (trap - INT; sleep 10) & wait
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
139862 13008 139862 S+ 0000000000380004 ./bash
139882 139862 139862 S+ 0000000000000004 ./bash
139883 139882 139862 S+ 0000000000000000 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
139862 13008 139862 S+ 0000000000380004 ./bash
...
$ (trap - INT; exec sleep 10) & wait
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
139862 13008 139862 S+ 0000000000380004 ./bash
139886 139862 139862 S+ 0000000000000000 sleep 10
...
^C
$ ps -eHo pid,ppid,pgid,stat,ignored,args
PID PPID PGID STAT IGNORED COMMAND
...
139862 13008 139862 S+ 0000000000380004 ./bash
...
The issue was supposedly fixed in 4.3-rc2
:
commit (4.3-rc2
)
commit (4.3
)
issue
+h. Fixed a bug that caused SIGINT and SIGQUIT to not be trappable in
+ asynchronous subshell commands.
https://git.savannah.gnu.org/cgit/bash.git/tree/CHANGES?h=bash-4.3-rc2&id=b6e23235f28b1c85e18e9a2b7ba8c6b6c46aecbc#n24
https://git.savannah.gnu.org/cgit/bash.git/tree/CHANGES?h=bash-4.3&id=ac50fbac377e32b98d2de396f016ea81e8ee9961#n67
+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