Change in SIGTERM behaviour in bash 4.3 when using readline

2020-03-04 Thread Chris Down

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

2020-03-04 Thread Chris Down
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

2020-03-04 Thread Chris Down

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

2020-03-04 Thread Chet Ramey
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

2020-03-04 Thread Greg Wooledge
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

2020-03-04 Thread Chet Ramey
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/