automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: shell errexit and exit status (was: [PATCH] Internationalization tes


From: Stefano Lattarini
Subject: Re: shell errexit and exit status (was: [PATCH] Internationalization tests: do not ignore failures.)
Date: Mon, 6 Sep 2010 21:22:51 +0200
User-agent: KMail/1.13.3 (Linux/2.6.30-2-686; KDE/4.4.4; i686; ; )

On Monday 06 September 2010, Ralf Wildenhues wrote:
> Hello Stefano,
> 
> * Stefano Lattarini wrote on Mon, Sep 06, 2010 at 05:06:23PM CEST:
> > This patch fixes potential false negatives in the new tests.
> > 
> > Internationalization tests: do not ignore failures.
> > 
> > Some tests used the idiom:
> >   test $builddir = '.' || test ! -f posub/foo-bar.pot
> > 
> > to check that a file is build in the source directory, not in
> > the build directory.  But even when the `errexit' shell flag
> > is active, the above does not abort the script even if the file
> > `posub/foo-bar.pot' exists, since the failing `test' is in a
> > `||' compound command.  Fix this problem by explicitly calling
> > `Exit 1' where needed.
> 
> I'm not sure I understand this rationale.  The problem, as I see
> it, is slightly different: with
> 
>   set -e
>   false || false
>   notreached
> 
> it is portable to assume that the last line in the script is not
> reached any more.  That is, you can be sure that the script will
> exit prematurely.
Oh.  Error on my part then: I erroneously thought that `false || false'
wouldn't have caused the shell to exit even with `set -e'!  Do you have
a link to the relevant part of the POSIX standard dealing with `set -e',
so that I can clear myself of other hideous misunderstandings?

AND: let's just drop this patch as useless, ok?

> However, with this script:
> 
>   trap 'st=$?; exit $st' EXIT
>   set -e
>   true && false
>   notreached
> 
> there is a problem with shells like Tru64 sh (and some others):
> the false causes the shell to not execute the last line of the
> script any more.  However, the value of $? at the time the EXIT
> trap is entered is still that of the 'true' command, so 0.  Only
> after the exit trap is finished, will the shell set $? to that of
> 'false'.  Problem is, the shell doesn't ever get to that point,
> because the 'exit' within the trap causes it to, well, exit before
> that, and with a status of $st which is 0.
> 
> This is why autoconf.texi has the following bits, and
> recommendation at the end:
> 
>      Portable scripts should not use `set -e' if `trap' is used to
>      install an exit handler.  This is because Tru64/OSF 5.1 `sh'
>      sometimes enters the trap handler with the exit status of the
>      command prior to the one that triggered the errexit handler:
> 
>           $ sh -ec 'trap '\''echo $?'\'' 0; false'
>           0
>           $ sh -c 'set -e; trap '\''echo $?'\'' 0; false'
>           1
> 
>      Thus, when writing a script in M4sh, rather than trying to
> rely on `set -e', it is better to append `|| AS_EXIT' to any
> statement where it is desirable to abort on failure.
> 
> The equivalent to `|| AS_EXIT' in the Automake testsuite is `||
> Exit 1'.
> 
> That also means, that we should probably be more cautious with
> removing `|| Exit 1' instances from tests.
Why?  The exit trap is currently not installed if a broken /bin/sh
is detected, is it?

> Or, here's a different idea: maybe we can somehow detect this shell
> feature at run time.  In that case it is sufficient to just *not*
> exit from within the trap (unless the trap code has caused another
> failure status that should be reported).
What about my pending patch "Testsuite: use $SHELL to run tests which
are shell scripts."?  That should ensure that the tests are run with
a decent shell.  Maybe we could then hack Automake's configure.ac to
ensure that configure reject shells exhibiting the trap bug.  What is
the status of ksh on Tru64/OSF 5.1?  Is it as broek as /bin/sh, or is
it usable for our purposes?

Regards, and sorry for the botched patch.
   Stefano



reply via email to

[Prev in Thread] Current Thread [Next in Thread]