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 -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html