* exit-ing in a trap handler uses the wrong exit code
@ 2010-09-25 11:59 Loïc Minier
2010-09-25 20:34 ` Jilles Tjoelker
0 siblings, 1 reply; 3+ messages in thread
From: Loïc Minier @ 2010-09-25 11:59 UTC (permalink / raw)
To: dash
Hi there
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.
Cheers,
NB: Not subscribed to the list, please Cc: me on replies
--
Loïc Minier
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: exit-ing in a trap handler uses the wrong exit code
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
2010-09-25 21:42 ` Loïc Minier
0 siblings, 1 reply; 3+ messages in thread
From: Jilles Tjoelker @ 2010-09-25 20:34 UTC (permalink / raw)
To: Loïc Minier; +Cc: dash
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: exit-ing in a trap handler uses the wrong exit code
2010-09-25 20:34 ` Jilles Tjoelker
@ 2010-09-25 21:42 ` Loïc Minier
0 siblings, 0 replies; 3+ messages in thread
From: Loïc Minier @ 2010-09-25 21:42 UTC (permalink / raw)
To: Jilles Tjoelker; +Cc: dash
On Sat, Sep 25, 2010, Jilles Tjoelker wrote:
> 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.
I don't know why it was put there in the first place, but my first
reaction was to send patch to remove the use of exit in the trap
handler:
http://lists.gnu.org/archive/html/qemu-devel/2010-09/msg01803.html
but the discussion led me to report this bug against dash
Thanks for your detailed reply! Am I also expected to log this issue
somewhere for tracking?
Cheers,
--
Loïc Minier
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-09-25 21:42 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2010-09-25 21:42 ` Loïc Minier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox