bin/159730: make(1) in parallel mode fails report failure of @-prefixed recipe using "set +e"

Jilles Tjoelker jilles at stack.nl
Sun Aug 14 12:20:13 UTC 2011


The following reply was made to PR bin/159730; it has been noted by GNATS.

From: Jilles Tjoelker <jilles at stack.nl>
To: bug-followup at FreeBSD.org
Cc: harti at FreeBSD.org
Subject: Re: bin/159730: make(1) in parallel mode fails report failure of
 @-prefixed recipe using &quot;set +e&quot;
Date: Sun, 14 Aug 2011 14:11:20 +0200

 Stefano Lattarini reports:
 > [echo 'all: ; @set +e; false' | make -j2 -f- fails to detect error]
 
 I can reproduce this.
 
 The cause is that make(1) runs all commands for a target in a single
 shell when -j is in effect. This shell has the -e and -v options
 initially enabled and reads the script from standard input. In that
 case, the '@' modifier is handled by surrounding the command with a line
 'set -' and a line 'set -v', and filtering the 'set -' from the output.
 (Similarly, the '+' modifier temporarily disables '-e'.)
 
 The 'set -v' has exit status 0 and masks the exit status from the
 command that was supposed to be tested.
 
 More generally, using a single shell in this manner will lead to results
 unexpected from the POSIX specification because changes to the shell
 environment remain in effect.
 
 A possible fix is to put each command (line) in a subshell environment
 with parentheses. To keep proper output, this requires replacing 'set
 -v' with explicit printf commands. If the command ends with an external
 program, this does not result in extra forks with our sh, although there
 will be more copy-on-write faults.
 
 By the way, having sh read the script from standard input will lead to
 suboptimal performance. One reason is that our sh has an optimization
 for -c that skips a fork for a final external program (with a few
 exceptions such as if there are trap handlers) but there is no such
 optimization for scripts named on the command line or commands passed
 via standard input. Another reason is that POSIX requires sh, when it is
 reading commands from standard input, to position the file pointer
 directly after each command before executing it. Our sh currently does
 not do this, however.
 
 If {ARG_MAX} permits, it is more efficient to pass the commands via -c.
 
 -- 
 Jilles Tjoelker


More information about the freebsd-bugs mailing list