Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save x-yuri/140fb815b866815d48d1237c78bb18a8 to your computer and use it in GitHub Desktop.
Save x-yuri/140fb815b866815d48d1237c78bb18a8 to your computer and use it in GitHub Desktop.
bash: interrupting commands with async subprocesses when job control is disabled

bash: interrupting commands with async subprocesses when job control is disabled

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment