Date: Tue, 10 Jul 2001 09:30:06 +0900 (JST) From: MORI Kouji <mori@tri.asanuma.co.jp> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/28852: behavior of /bin/sh with -e option looks incorrect Message-ID: <20010710.093006.126640528.mori@tri.asanuma.co.jp>
next in thread | raw e-mail | index | archive | help
>Number: 28852
>Category: bin
>Synopsis: behavior of /bin/sh with -e option looks incorrect
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Jul 09 17:40:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:
>Release: FreeBSD 4.3-STABLE i386
>Organization:
Techinical Reserach Institute, Asanuma Corp., Takatsuki, Japan
>Environment:
System: FreeBSD kurishna.tri.asanuma.co.jp 4.3-STABLE FreeBSD 4.3-STABLE #54: Fri Jun 22 11:28:51 JST 2001 mori@kurishna.tri.asanuma.co.jp:/opt/FreeBSD-RELENG_4/obj/opt/FreeBSD-RELENG_4/src/sys/KOTONE i386
>Description:
In sh(1), about '-e' and 'errexit' is follows description.
-e errexit
Exit immediately if any untested command fails in non-interactive
mode. The exit status of a command is considered to be explicit-
ly tested if the command is used to control an if, elif, while,
or until; or if the command is the left hand operand of an ``&&''
or ``||'' operator.
But in 'if' statement, if a left command of '&&' failes then
exit immediately.
This behavior is found doing follows command. And this is found
only in FreeBSD and NetBSD.
$ sh -ecx 'if true; then false && true; fi; true'
+ true
+ false
$
In bash-2.05,
$ bash -ecx 'if true; then false && true; fi; true'
+ true
+ false
+ true
$
In SunOS 5.7's /bin/sh
$ /bin/sh -ecx 'if true; then false && true; fi; true'
+ true
+ false
+ true
In SunOS 5.7's /bin/ksh
$ /bin/ksh -ecx 'if true; then false && true; fi; true'
+ true
+ false
+ true
$
>How-To-Repeat:
Do follow command, please.
We expect last 'true', but isn't appeared.
$ sh -ecx 'if true; then false && true; fi; true'
+ true
+ false
$
>Fix:
Index: eval.c
===================================================================
RCS file: /opt/cvs/FreeBSD/src/bin/sh/eval.c,v
retrieving revision 1.27.2.3
diff -u -r1.27.2.3 eval.c
--- eval.c 2001/07/05 00:41:14 1.27.2.3
+++ eval.c 2001/07/09 23:55:18
@@ -208,7 +208,6 @@
case NAND:
evaltree(n->nbinary.ch1, EV_TESTED);
if (evalskip || exitstatus != 0) {
- flags |= EV_TESTED;
goto out;
}
evaltree(n->nbinary.ch2, flags);
@@ -249,25 +248,9 @@
break;
case NFOR:
evalfor(n);
- /*
- * The 'for' command does not set exitstatus, so the value
- * now in exitstatus is from the last command executed in
- * the 'for' loop. That exit value had been tested (wrt
- * 'sh -e' checking) while processing that command, and
- * it should not be re-tested here.
- */
- flags |= EV_TESTED;
break;
case NCASE:
evalcase(n, flags);
- /*
- * The 'case' command does not set exitstatus, so the value
- * now in exitstatus is from the last command executed in
- * the 'case' block. That exit value had been tested (wrt
- * 'sh -e' checking) while processing that command, and
- * it should not be re-tested here.
- */
- flags |= EV_TESTED;
break;
case NDEFUN:
defun(n->narg.text, n->narg.next);
@@ -292,14 +275,8 @@
out:
if (pendingsigs)
dotrap();
- /*
- * XXX - Like "!(n->type == NSEMI)", more types will probably
- * need to be excluded from this test. It's probably better
- * to set or unset EV_TESTED in the loop above than to bloat
- * the conditional here.
- */
if ((flags & EV_EXIT) || (eflag && exitstatus
- && !(flags & EV_TESTED) && !(n->type == NSEMI)))
+ && !(flags & EV_TESTED) && (n->type == NCMD)))
exitshell(exitstatus);
}
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010710.093006.126640528.mori>
