-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 [moving to autoconf-patches, replies can drop autoconf] According to jens.schmidt35@xxxxxxxx on 4/29/2009 3:40 AM: > Hi. Hi Jens, and sorry it has taken me so long to respond to your suggestions. > There it says in section "Limitation of Shell Builtins": > > Posix says that ‘trap - 1 2 13 15’ resets the traps for the specified signals to > their default values, but many common shells (e.g., Solaris /bin/sh) misinterpret > this and attempt to execute a “command” named - when the specified > conditions arise. There is no portable workaround, except for ‘trap - 0’, for > which ‘trap ’’ 0’ is a portable substitute. > > I do not entirely agree with the latter statement. It seems that 'trap 1 2 13 15' (without any command) reset the traps in a reasonably portable way, as documented also in the sh man pages. I tested the following on AIX, HP-UX (SPARC & x86-64), HP-UX (PA-RISC & IA64), Tru64, Linux (x86, x86-64, IA64, PPC) (yes, I wanted to show off a bit): As was pointed out in the thread, POSIX 2008 requires this behavior, but it is not yet portable (at least dash fails this, so your tests were not exhaustive). > > On Solaris 9, /bin/sh does not execute a trap on exit if in a parenthesised sub-shell if the last command is not a built-in: > > $ ( trap "echo foo" 0; :; true ) > $ ( trap "echo foo" 0; true; : ) > foo > > Of course, the error diagnosis may not entirely precise. Better it would be to say: "On Solaris 9, /bin/sh may not execute a trap on exit if the trap is defined in a parenthesised sub-shell." > > A workaround may be to always exit explicitly with "exit $?" from the sub-shell. I added an example of this. > Another reason to be careful with "set -e" on Solaris 10: A failing command substitution may not be caught by any means if option "-e" is set. The shell bails out immediately: > > $ ( set -e; foo=`false` || echo "foo"; echo "bar" ); echo "baz" > baz I've mentioned this. > Older Bashes (mine is 2.05b.0(1)) may forget exit values if there is a trap on exit set and if the trap consists of one succeeding external command only. Seems to be fixed in latest Bashes. > > $ /bin/bash -c 'trap "/bin/true" 0; exit 2'; echo $? > 0 > $ /bin/bash -c 'trap ":; /bin/true" 0; exit 2'; echo $? > 2 > > I hit that problem when I had a "rm -f " clean-up trap in a canned sequence in a makefile, where the sequence failed but "make" did not take any notice of that fact due to this bug ... not too exotic an use-case, I think. Also good to mention, especially since it has a workaround. Here's what I'm applying: - -- Don't work too hard, make some time for fun as well! Eric Blake ebb9@xxxxxxx -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkorPLAACgkQ84KuGfSFAYDuQgCggTpzobCv65JWsgjVDi1s6K/l WSEAoMOysv7aSF03/Mh2Cz/LyTh5/R8F =uHHh -----END PGP SIGNATURE-----
From 16a04c38e16cfb451bdfe561d2856068aa28c2a2 Mon Sep 17 00:00:00 2001 From: Eric Blake <ebb9@xxxxxxx> Date: Sat, 6 Jun 2009 22:03:16 -0600 Subject: [PATCH] Improve documentation on trap pitfalls. * doc/autoconf.texi (Limitations of Builtins) <trap>: Mention new Posix 2008 requirement on trap, and dash bug in implementing it. Mention various shell bugs with traps defined inside subshells. Mention older bash limitation with single-command exit trap. <set>: Mention another 'set -e' limitation. Reported by Jens Schmidt. Signed-off-by: Eric Blake <ebb9@xxxxxxx> --- ChangeLog | 8 ++++++++ doc/autoconf.texi | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9a7ccf7..a9bd462 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2009-06-06 Eric Blake <ebb9@xxxxxxx> + Improve documentation on trap pitfalls. + * doc/autoconf.texi (Limitations of Builtins) <trap>: Mention new + Posix 2008 requirement on trap, and dash bug in implementing it. + Mention various shell bugs with traps defined inside subshells. + Mention older bash limitation with single-command exit trap. + <set>: Mention another 'set -e' limitation. + Reported by Jens Schmidt. + Avoid ambiguous fallback in AC_PROG_CXX, AC_PROG_OBJC. * lib/autoconf/c.m4 (AC_PROG_CXX, AC_PROG_OBJC): Use 'no', rather than an ambiguous compiler name, when no compiler is present. diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 215c864..81bce07 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -16188,6 +16188,16 @@ Limitations of Builtins "$foo"; then exit 1; fi} rather than @samp{test -n "$foo" && exit 1}. Another possibility is to warn @acronym{BSD} users not to use @samp{sh -e}. +When @samp{set -e} is in effect, a failed command substitution in +Solaris @command{/bin/sh} cannot be ignored, even with @samp{||}. + +@example +$ @kbd{/bin/sh -c 'set -d; foo=`false` || echo foo; echo bar'} +$ @kbd{bash -c 'set -d; foo=`false` || echo foo; echo bar'} +foo +bar +@end example + Portable scripts should not use @samp{set -e} if @command{trap} is used to install an exit handler. This is because Tru64/OSF 5.1 @command{sh} sometimes enters the trap handler with the exit status of the command @@ -16345,7 +16355,11 @@ Limitations of Builtins specified signals to their default values, but many common shells (e.g., Solaris @command{/bin/sh}) misinterpret this and attempt to execute a ``command'' named @command{-} when the specified conditions arise. -There is no portable workaround, except for @samp{trap - 0}, for which +Posix 2008 also added a requirement to support @samp{trap 1 2 13 15} to +reset traps, as this is supported by a larger set of shells, but there +are still shells like @command{dash} that mistakenly try to execute +@command{1} instead of resetting the traps. Therefore, there is no +portable workaround, except for @samp{trap - 0}, for which @samp{trap '' 0} is a portable substitute. Although Posix is not absolutely clear on this point, it is widely @@ -16390,6 +16404,31 @@ Limitations of Builtins @noindent Fortunately, this bug only affects @command{trap}. +Several shells fail to execute an exit trap that is defined inside a +subshell, when the last command of that subshell is not a builtin. A +workaround is to use @samp{exit $?} as the shell builtin. + +@example +$ @kbd{bash -c '(trap "echo hi" 0; /bin/true)'} +hi +$ @kbd{/bin/sh -c '(trap "echo hi" 0; /bin/true)'} +$ @kbd{/bin/sh -c '(trap "echo hi" 0; /bin/true; exit $?)'} +hi +@end example + +@noindent +Likewise, older implementations of @command{bash} failed to preserve +@samp{$?} across an exit trap consisting of a single cleanup command. + +@example +$ @kbd{bash -c 'trap "/bin/true" 0; exit 2'; echo $?} +2 +$ @kbd{bash-2.05b -c 'trap "/bin/true" 0; exit 2'; echo $?} +0 +$ @kbd{bash-2.05b -c 'trap ":; /bin/true" 0; exit 2'; echo $?} +2 +@end example + @item @command{true} @c ----------------- @prindex @command{true} -- 1.6.3.rc3.2.g4b51
_______________________________________________ Autoconf mailing list Autoconf@xxxxxxx http://lists.gnu.org/mailman/listinfo/autoconf