help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Interrupting scripts with asynchronous subprocesses


From: Yuri Kanivetsky
Subject: Re: Interrupting scripts with asynchronous subprocesses
Date: Mon, 1 Jul 2024 19:02:36 +0300

Let me try again. Basically c.sh is possible since 4.3-rc2:

https://gist.github.com/x-yuri/50e045babaddc6b1779d8414c825705d

Consider the following command:

$ bash -c '(trap INT; sleep infinity) & wait'

Before 4.3-rc2 you'd get a subshell with `SIGINT == SIG_DFL` and sleep
with `SIGINT == SIG_IGN`. SIG_IGN on sleep wouldn't let the subshell
to exit:

https://git.savannah.gnu.org/cgit/bash.git/tree/jobs.c?h=bash-4.3-rc2&id=8581f42df9a1b1d848e2d4bdf3cc951b8d14b5be#n2276

In this case the subshell's original_signals[SIGINT] would be set to SIG_IGN:

https://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c?h=bash-4.3-rc2&id=8581f42df9a1b1d848e2d4bdf3cc951b8d14b5be#n4798
https://git.savannah.gnu.org/cgit/bash.git/tree/trap.c?h=bash-4.3-rc2&id=8581f42df9a1b1d848e2d4bdf3cc951b8d14b5be#n1214

And that is what sleep would get:

https://git.savannah.gnu.org/cgit/bash.git/tree/trap.c?h=bash-4.3-rc2&id=8581f42df9a1b1d848e2d4bdf3cc951b8d14b5be#n1138
https://git.savannah.gnu.org/cgit/bash.git/tree/trap.c?h=bash-4.3-rc2&id=8581f42df9a1b1d848e2d4bdf3cc951b8d14b5be#n1074

After 4.3-rc2 original_signals[SIGIGN] is no longer set to SIG_IGN:

https://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c?h=bash-4.3-rc2&id=b6e23235f28b1c85e18e9a2b7ba8c6b6c46aecbc#n4816

They'd both have SIG_DFL and both would exit.

Now, in this case:

a.sh:

    trap INT
    sleep infinity

$ bash -c 'bash a.sh & wait'

Everything remains as it was before 4.3-rc2 in the other case. Or
should I say at least since 4.0, which feels like the beginning of
times these days. The subshell has SIG_DFL, sleep has SIG_IGN and they
both remain. With an arbitrary trap (echo $$: INT; trap INT; kill -2
$$), they both have SIG_IGN and both remain.

My best guess would be that it has to do with the following POSIX requirement:

> A signal ignored on entry to the shell cannot be trapped or reset, but no 
> error is reported when attempting to do so.  -- Posix.2

https://git.savannah.gnu.org/cgit/bash.git/tree/trap.c?h=bash-5.2#n800

So basically if we do `(trap ...) &` this doesn't count as "on entry
to the shell" and we can override SIGINT. But when we do `bash a.sh &`
and try to handle SIGINT there, that is interpreted as a new shell and
can't be allowed. Except that one can reset SIGINT in a.sh in the
latter case at least since 4.0. Well maybe since what bash mostly does
is runs external processes and external processes will receive
SIG_IGN, that doesn't make much difference? What do you say?

Regards,
Yuri



reply via email to

[Prev in Thread] Current Thread [Next in Thread]