Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug with traps and exit

On Sun, Dec 15, 2019 at 9:25 PM Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx> wrote:
> workers/44007 (also in this thread):
> > trap 'printf $1; exit; printf $2' USR1
> > fn() {
> >         printf 1
> >         kill -s usr1 $$
> >         printf 2
> > }
> > printf 0
> > fn A B
> > printf 3
> Here, Martijn was saying that zsh should print 01A but in fact prints 01A2.

Have a look at the "shell_exiting" global manipulated in builtin.c.
(Some comments still refer to "in_exit" which IIRC was replaced by

> This suggests the 'exit' inhibits «printf $2» and «printf 3» from running, but
> doesn't inhibit «printf 2» (without a dollar sign) from running.  How would
> you approach something like this?  I'm guessing bin_exit should set a global
> volatile int variable to '1' if it's called from a signal handler, but where
> would that variable be checked?

Note that "from_where" in zexit() already indicates whether we are
coming from a signal, but bin_break (which handles BIN_EXIT) does not
treat "in a signal handler" as "coming from a signal" when calling
zexit().  This is why the function continues running -- zexit() passes
from_where = 2 ("can't actually exit yet"), I suspect in order to
allow running an EXIT trap set by the function itself.

The trouble is that we also have to treat differently the cases of the
trap having been set inside the function, and the trap existing
outside the function when the function is called.  Trivially treating
exit from a handler the same as being killed by signal whose default
behavior is to exit, leads to failures in the test suite.

Messages sorted by: Reverse Date, Date, Thread, Author