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>