From: Jilles Tjoelker <jilles@stack.nl>
To: "Loïc Minier" <lool@dooz.org>
Cc: dash@vger.kernel.org
Subject: Re: exit-ing in a trap handler uses the wrong exit code
Date: Sat, 25 Sep 2010 22:34:04 +0200 [thread overview]
Message-ID: <20100925203404.GA93010@stack.nl> (raw)
In-Reply-To: <20100925115900.GA9732@bee.dooz.org>
On Sat, Sep 25, 2010 at 01:59:00PM +0200, Loïc Minier wrote:
> qemu's configure uses a trap handler which calls exit; configure would
> call exit 1, but with the trap handler in place the configure script
> would return with exit 0.
> dash -c 'trap "sh -c \"exit 4\"; exit" 0 1 2 3 9 11 13 15;exit 3'; echo $?
> 4
> Blue Swirl on the qemu-devel list points out that according to POSIX
> this should be 3:
> http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_21
> bash and zsh get this right:
> bash -c 'trap "sh -c \"exit 4\"; exit" 0 1 2 3 9 11 13 15;exit 3'; echo $?
> 3
> I've logged https://bugs.launchpad.net/ubuntu/+source/dash/+bug/647450
> to track this as I'm seeing this with the Ubuntu version of dash.
You are certainly right that POSIX requires this to be handled
differently, but there are various other shells that are non-compliant
in the same way as dash and it is easy to avoid the behaviour, so I
would not recommend depending on it.
Other shells where 'exit' is equivalent to 'exit $?' even in traps:
NetBSD /bin/sh, FreeBSD /bin/sh (both of these are related to dash),
pdksh, mksh, the original Bourne shell (from the Heirloom toolchest).
Of course this is no guarantee that these shells will not be changed to
be compliant later on, but many deployed systems use a /bin/sh that is
not compliant in this regard.
To avoid the behaviour, only use the exit special builtin in a trap
action for EXIT if you want to override the exit status. If you do not
use exit, all shells preserve the exit status.
For signals, the trap action should typically terminate the process,
either via exit with an explicit non-zero status, or (more properly) by
resetting the trap to its default action and resending the signal. Using
exit without parameters in a signal trap action appears to return status
0 in bash and zsh, which seems less than useful. Only in ksh93 does this
do something useful: it resets the signal to its default action and
resends it; however, if the signal is one that is ignored by default
ksh93 hangs forever.
POSIX says that the same applies to the return special builtin (even
though POSIX only specifies returning from functions or dot scripts, not
from shell instances). This does not appear to make much sense to me,
and bash does not implement it (it does not allow returning from shell
instances either, while dash and ksh93 do).
Further remarks:
* Trying to trap SIGKILL produces undefined results, don't do it.
* Trapping SIGSEGV may cause unexpected results unless the signal was
sent via kill(), sigqueue() or similar. Ash variants return from the
signal handler after setting a flag, which usually causes an infinite
loop as the problematic instruction is retried over and over again. They
do not use a signal stack (sigaltstack()), so a stack overflow will
terminate the process immediately. In any case, if the shell itself gets
an actual SIGSEGV, its state is probably too messed up to continue
executing a script.
--
Jilles Tjoelker
next prev parent reply other threads:[~2010-09-25 20:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-25 11:59 exit-ing in a trap handler uses the wrong exit code Loïc Minier
2010-09-25 20:34 ` Jilles Tjoelker [this message]
2010-09-25 21:42 ` Loïc Minier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100925203404.GA93010@stack.nl \
--to=jilles@stack.nl \
--cc=dash@vger.kernel.org \
--cc=lool@dooz.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox