Subject: bug#15779: timeout: Child gets SIGTTOU when run from a shell script

From: Pádraig Brady <[email-masked]>
Date: Fri, 01 Nov 2013 13:48:45 +0000

On 11/01/2013 12:17 PM, Richard W.M. Jones wrote:
> On Fri, Nov 01, 2013 at 11:53:44AM +0000, Pádraig Brady wrote:
>> Probably something to do with job control
>> If you `set -m` first in the script,
>> then the test binary doesn't hang.
> 
> Unfortunately set -m isn't quite right for the script
> we are interested in fixing:
> 
> https://github.com/libguestfs/libguestfs/blob/master/run.in#L217
> 
>> 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.
> 
> That sounds like a very similar situation to this one.  The
> tty_check_change function is called all over the place, so just about
> any ioctl or flush or tc* function could cause SIGTTOU to be sent.
> 
>> Maybe we should be resetting SIGTT{OU,IN} to what it was
>> previously set to, rather than SIG_DFL?
> 
> The attached patch does *not* work .. don't know if you can see
> any obvious mistakes.
> 
> Yesterday I looked through the strace -f output between the two cases
> and came to the conclusion that it's not about signal handlers at all.
> (What it's about is a mystery ...)
> 
> Rich.

The initial messages to bug-coreutils have disappeared somewhere in the ether.
Anyway the context is that if a process being controlled by timeout
gets a SIGTTOU, then it will be stopped. Note timeout handles this case
by killing the process when the timeout occurs, but that doesn't help
as the process will be stalled for the duration of the timeout.
Details at: https://bugzilla.redhat.com/1025269

The workaround was to remove the calls to set SIGTTOU to SIG_DFL
just before the child is exec'd, however I'm not sure about that
since we want to treat monitored timeout jobs like background
processes, and if you run the problematic test child as a standard
shell background job, it's stopped also:

 $ /tmp/test&
 [2]+  Stopped                 /tmp/test

The proposed workaround mentioned in the quoted text above is ineffective.

I think that since the child wants to "interact" with the tty,
that adding the --foreground option to the timeout command is appropriate here?
The caveat is that children of the monitored command will not be timed out.

thanks,
Pádraig.

p.s. I wonder would cgroups when available
give a more powerful "process tree" timeout control functionality