Change in SIGTERM behaviour in bash 4.3 when using readline
Hi there, A question on Unix & Linux Stack Exchange[0] brought up the question of SIGTERM terminating interactive bash shells. This surprised me, and after bisecting I narrowed it down to commit ac50fbac ("Bash-4.3 distribution sources and documentation"). Going through the commit I see a significant number of changes, like the addition of setting/checking the sigterm_received atomic in a number of places, and the special handling of some signals (including SIGTERM) as part of deciding whether to call rl_signal_event_hook. It seems this behaviour is related to readline, because it goes away if I run with --noediting. Before I spend the time to look through the code to work out exactly which part of ac50fbac results in this behaviour, since it's fairly substantial, I want to double check -- was this an intentional change or not? I can't really tell from CHANGES or NEWS: they mention some of the compile-time options around SIGTERM and rl_signal_event_hook, but I can't really tell the intent when it comes to this behaviour in particular. Certainly it came as a surprise to me, at least. Thanks, Chris 0: https://unix.stackexchange.com/q/571123/10762
Re: Change in SIGTERM behaviour in bash 4.3 when using readline
Ah, it's been a while since I did this and I forgot about the granularity of the devel branch :-) There it bisects to 73a146bec7f75da9f78f6d54329c980b75a2318d ("commit bash-20130215 snapshot"). I'm pretty sure it's related to this change to add the signal handler inside initialize_shell_signals, which sets a new handler if SIGTERM isn't SIG_HARD_IGNORE. If I read the code correctly, in that case we will resume due to SA_RESTART, but bubbling up readline() will now return 0, which will be passed to yy_readline_get(), which returns EOF if current_readline_line is 0, so the shell closes. I'm not quite sure how best to handle this, maybe setting SIG_IGN as the default signal handler for interactive shells if there's nothing to inherit? This is one of those cases where SA_RESTART doesn't quite mimic SIG_IGN...
Re: Change in SIGTERM behaviour in bash 4.3 when using readline
Chris Down writes: I'm not quite sure how best to handle this, maybe setting SIG_IGN as the default signal handler for interactive shells if there's nothing to inherit? This is one of those cases where SA_RESTART doesn't quite mimic SIG_IGN... This seems too simple, so I assume it's going to cause other problems, but: --- jobs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/jobs.c b/jobs.c index e157c38f..a57b7082 100644 --- a/jobs.c +++ b/jobs.c @@ -4584,6 +4584,7 @@ initialize_job_signals () if (interactive) { set_signal_handler (SIGINT, sigint_sighandler); + set_signal_handler (SIGTERM, SIG_IGN); set_signal_handler (SIGTSTP, SIG_IGN); set_signal_handler (SIGTTOU, SIG_IGN); set_signal_handler (SIGTTIN, SIG_IGN); -- 2.25.1
Re: Change in SIGTERM behaviour in bash 4.3 when using readline
On 3/4/20 2:38 PM, Chris Down wrote: > Chris Down writes: >> I'm not quite sure how best to handle this, maybe setting SIG_IGN as the >> default signal handler for interactive shells if there's nothing to >> inherit? This is one of those cases where SA_RESTART doesn't quite mimic >> SIG_IGN... > > This seems too simple, so I assume it's going to cause other problems, but: > > --- > jobs.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/jobs.c b/jobs.c > index e157c38f..a57b7082 100644 > --- a/jobs.c > +++ b/jobs.c > @@ -4584,6 +4584,7 @@ initialize_job_signals () > if (interactive) > { > set_signal_handler (SIGINT, sigint_sighandler); > + set_signal_handler (SIGTERM, SIG_IGN); This is how the code used to read, before I added the do-nothing signal handler as a result of https://lists.gnu.org/archive/html/bug-bash/2013-02/msg00020.html There is another way to do it by blocking signals, and a comment in the code indicates that I considered using it for SIGTERM at the time. Ignoring the signal is what caused the race condition in the first place. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: Change in SIGTERM behaviour in bash 4.3 when using readline
On Wed, Mar 04, 2020 at 03:43:26PM -0500, Chet Ramey wrote: > On 3/4/20 2:38 PM, Chris Down wrote: > > --- a/jobs.c > > +++ b/jobs.c > > @@ -4584,6 +4584,7 @@ initialize_job_signals () > > if (interactive) > > { > > set_signal_handler (SIGINT, sigint_sighandler); > > + set_signal_handler (SIGTERM, SIG_IGN); > > This is how the code used to read, before I added the do-nothing signal > handler as a result of > > https://lists.gnu.org/archive/html/bug-bash/2013-02/msg00020.html The man page might need an update as well. SIGNALS When bash is interactive, in the absence of any traps, it ignores SIGTERM (so that kill 0 does not kill an interactive shell) [...]
Re: Change in SIGTERM behaviour in bash 4.3 when using readline
On 3/4/20 2:29 PM, Chris Down wrote: > Ah, it's been a while since I did this and I forgot about the granularity > of the devel branch :-) > > There it bisects to 73a146bec7f75da9f78f6d54329c980b75a2318d ("commit > bash-20130215 snapshot"). I'm pretty sure it's related to this change to > add the signal handler inside initialize_shell_signals, which sets a new > handler if SIGTERM isn't SIG_HARD_IGNORE. > > If I read the code correctly, in that case we will resume due to > SA_RESTART, but bubbling up readline() will now return 0, which will be > passed to yy_readline_get(), which returns EOF if current_readline_line is > 0, so the shell closes. > > I'm not quite sure how best to handle this, maybe setting SIG_IGN as the > default signal handler for interactive shells if there's nothing to > inherit? This is one of those cases where SA_RESTART doesn't quite mimic > SIG_IGN... It has the same effect when called, but the key change is that readline, noticing that SIGTERM is not ignored when it starts, installs its own signal handler, which sets _rl_caught_signal accordingly. Then SIGTERM interrupts the read, returns READERR/EOF, and we go from there (readline only installs its SIGWINCH handler with SA_RESTART, since that is the right thing for most applications). Another consideration for treating SIGTERM and SIGHUP the same inside the readline input code was the existence of terminal handlers that sent SIGTERM when a user pressed the `close' button. If you don't return an error in that case, readline just spins in the background. If someone can guarantee to me that there are no remaining terminal emulators that send SIGTERM in that case (that is, everyone sends SIGHUP and possibly revokes read access from the process read size of the pty), we can remove SIGTERM's special handling inside readline's input code and let it be handled like other signals. Terminal emulators have evolved considerably since then, so it might be possible to guarantee this. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/