Re: dash 0.5.11.2, busybox sh 1.32.0, FreeBSD 12.2 sh: spring TTOU but should not i think

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

 



On 21/12/2020 16:24, Jilles Tjoelker wrote:
Also, simply entering the command
     trap "echo TTOU" TTOU
in an interactive shell makes it behave strangely. Created jobs
immediately stop, "fg" works once but after that the shell tends to get
stuck quickly.

Good catch, there is some work to be done there too.

This seems a good approach, but certain writes to the terminal may need
the same treatment, for example the error message when fork fails for
the second and further elements of a pipeline. This also makes me wonder
why SIGTTOU is ignored at all by default.

True. This is hard to create a reliable test case for, but there is only limited code that can get executed while a job-control-enabled shell may not be in the foreground process group.

If fork fails halfway through a pipeline, it may also be a problem that some of the commands in the pipeline may still run.

In mksh, the issue is resolved slightly differently: setting a trap on
TTOU pretends to work but the signal disposition remains set to ignored.

zsh also rejects traps on TTOU, but does so explicitly:

  zsh: can't trap SIGTTOU in interactive shells

Amusingly, it prints this in any shell where job control is enabled, regardless of whether the shell is interactive.

Tradition is for job control shells to be a process group leader, but I
don't really know why. Changing this will not fix the issue entirely
anyway since the shell must perform tcsetpgrp() from the background when
a foreground job has terminated.

I've been thinking more about this, and I suspect it's a another conflation between interactive mode and job control. In an interactive shell that's not executing any external program, you want any Ctrl-C to only send SIGINT to that shell, not to any other process. In order for that to work, it needs to be its own process group.

This should, in my opinion, *only* happen for interactive shells, not for job-control-enabled non-interactive shells. Consider

  sh -c 'sh -mc "while :; do :; done"; echo bye'

The behaviour I would want is that Ctrl-C kills the parent shell, so that this does not print "bye". Different shells behave differently.

What is definitely required, though, is that the shell not read input or
alter terminal settings if it is started in the background (possibly
unless the script explicitly ignored SIGTTOU). This is what the loop
with tcgetpgrp() does.

Definitely.

Cheers,
Harald van Dijk



[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux