GNU bug report logs - #15781
timeout: Child gets SIGTTOU when run from a shell script

Previous Next

Package: coreutils;

Reported by: Pádraig Brady <pbrady <at> redhat.com>

Date: Fri, 1 Nov 2013 13:43:03 UTC

Severity: normal

Merged with 15779

Full log


Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <pbrady <at> redhat.com>
To: "Richard W.M. Jones" <rjones <at> redhat.com>
Cc: Report bugs to <bug-coreutils <at> gnu.org>
Subject: Re: timeout: Child gets SIGTTOU when run from a shell script
Date: Fri, 01 Nov 2013 11:53:44 +0000
On 11/01/2013 08:10 AM, Richard W.M. Jones wrote:
> Grab the tiny 'run' and 'test.c' attachments from here:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1025269#c5
> 
> $ cd /tmp
> $ gcc -Wall test.c -o test
> $ ./test                             # this is ok
> $ timeout 4h ./test                  # this is ok
> 
> $ cat ./run
> #!/bin/bash -
> timeout 4h ./test
> 
> $ ./run                              # this HANGS
> 
> The run script simply runs the same timeout command as before, from a
> shell script, but this time the test child process gets SIGTTOU and
> suspends itself, resulting in a hang.
> 
> I was able to fix this by *removing* the following lines in
> src/timeout.c:
> 
>        /* exec doesn't reset SIG_IGN -> SIG_DFL.  */
>        signal (SIGTTIN, SIG_DFL);
>        signal (SIGTTOU, SIG_DFL);
> 
> In other words, leave SIGTTOU as SIG_IGN in the child process (which
> seems to make sense -- since the child is a backgrounded process, but
> we want it to be able to print things, we don't want it to get SIGTTOU
> signals when it outputs to the terminal).
> 
> Anyway, I don't understand why this only happens when run from a shell
> script, and not from a terminal.  Presumably bash does something
> strange with SIGTTOU.

Probably something to do with job control
If you `set -m` first in the script,
then the test binary doesn't hang.

> Also I don't understand from looking at the kernel code why it's
> sending SIGTTOU in one case but not the other.  The relevant code is
> in drivers/tty/tty_io.c:tty_check_change but AFAICT it should send the
> signal in both cases.
> 
> Rich.
> 

Ugh these signals are really hairy to think about,
there are all sorts of edge cases here.

I did a version of timeout once that put the child in it's own group,
and noted in that version that I needed to leave SIGTTOU as IGN
as tcsetpgrp(0, getpid()) caused SIGTTOU to be sent and I wasn't sure why.

Maybe we should be resetting SIGTT{OU,IN} to what it was
previously set to, rather than SIG_DFL?

Pádraig.




This bug report was last modified 11 years and 285 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.