bug-bash
[Top][All Lists]
Advanced

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

Re: "wait" loses signals


From: Harald van Dijk
Subject: Re: "wait" loses signals
Date: Mon, 24 Feb 2020 19:29:21 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:73.0) Gecko/20100101 Thunderbird/73.0

On 24/02/2020 08:59, Robert Elz wrote:
harald@gigawatt.nl said:
   | In the same way, I think that except when overridden by 2.11, the "when"
   | in "Otherwise, the argument action shall be read and executed by the
   | shell when one of the corresponding conditions arises." should be
   | interpreted as "as soon as".

The only way to do that literally would be to run the trap from the signal
handler, as that is "as soon as" the condition arises.   But I think we all
know that is simply not possible.   So let's read that as "as soon as
possible after" instead.

Sure.

                           That's getting more reasonable, but someone needs
to decide just what is possible - will running the trap handler mess up the
shell's internal state while a new command is parsed and executed?

Eg: what if we had
        VAR=$(grep  -c some_string file*.c)
and a (trapped) signal arrives while grep is running (more correctly, while
the process running the command substitution, which runs grep, is running).
We know we cannot interrupt the wait for that foreground process to run the
trap handler, so we don't - but do we execute the trap handler before we
assign the answer to VAR ?

Although 2.11 that you referred to states "When a signal for which a trap has been set is received while the shell is waiting for the completion of a utility executing a foreground command", that is not what any shell implements. Instead, what shells implement is more like "while the shell is waiting for the completion of a foreground command". Consider for instance (sleep 5): the sleep command run in a subshell. The parent shell is not waiting for the completion of a utility executing a foreground command, the parent shell is waiting for the completion of the subshell, which is not a utility. Nevertheless, shells do not run any trap action until after the subshell has completed.

This is just sloppy wording in the standard. It is probably written this way so that it is clear that given { foo; bar; }, if a signal is received while foo is running, any trap action runs before bar. The whole compound command shouldn't be considered the foreground command, only foo should be.

In your example, I would expect the whole of VAR=$(...) to be considered the foreground command that the shell is waiting for, and that is what almost all shells do. A notable exception is zsh.

This kind of thing is why shells in general only normally even look to
see if there is a trap handler waiting to run after completing executing
commands, not in the middle of one.

The relevance of this is that if a signal arrives while the wait command
is executing (or as Chet suggested, while doing whatever housekeeping is
needed to prepare to run it, like looking to see what command comes next)
but before the relevant wait*() system call is running, the trap won't
be run until after the wait command completes.

That's the way shells have always worked, and the way the standard (for that
very reason) says can be relied upon by scripts - which is much of its
purpose, to tell script writers what they can expect will work, and what
will not necessarily work.

You say "have always worked", but I'd like to point out that this whole thing started because I was looking at code that Herbert Xu had changed in dash to avoid this race back in 2009. That's over 10 years ago now. The behaviour of dash before that, and several shells now, can not, or at least not now, be said to be how shells have always worked.

Cheers,
Harald van Dijk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]