sh: Fix $? in the first command of a 'for'.
authorPeter Avalos <pavalos@dragonflybsd.org>
Sun, 5 Feb 2012 20:12:44 +0000 (12:12 -0800)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sun, 5 Feb 2012 20:48:25 +0000 (12:48 -0800)
In the first command of a 'for', $? should be the exit status of the last
pipeline (command substitution in the word list or command before 'for'),
not always 0.

Obtained-from:  FreeBSD 230463

bin/sh/eval.c
tools/regression/bin/sh/builtins/for2.0 [new file with mode: 0644]
tools/regression/bin/sh/builtins/for3.0 [new file with mode: 0644]

index 3b3dea0..b1d250b 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  * @(#)eval.c  8.9 (Berkeley) 6/8/95
- * $FreeBSD: src/bin/sh/eval.c,v 1.118 2012/01/16 11:07:46 dumbbell Exp $
+ * $FreeBSD: src/bin/sh/eval.c,v 1.119 2012/01/22 14:00:33 jilles Exp $
  */
 
 #include <sys/time.h>
@@ -349,6 +349,7 @@ evalfor(union node *n, int flags)
        union node *argp;
        struct strlist *sp;
        struct stackmark smark;
+       int status;
 
        setstackmark(&smark);
        arglist.lastp = &arglist.list;
@@ -358,11 +359,12 @@ evalfor(union node *n, int flags)
        }
        *arglist.lastp = NULL;
 
-       exitstatus = 0;
        loopnest++;
+       status = 0;
        for (sp = arglist.list ; sp ; sp = sp->next) {
                setvar(n->nfor.var, sp->text, 0);
                evaltree(n->nfor.body, flags);
+               status = exitstatus;
                if (evalskip) {
                        if (evalskip == SKIPCONT && --skipcount <= 0) {
                                evalskip = 0;
@@ -375,6 +377,7 @@ evalfor(union node *n, int flags)
        }
        loopnest--;
        popstackmark(&smark);
+       exitstatus = status;
 }
 
 
diff --git a/tools/regression/bin/sh/builtins/for2.0 b/tools/regression/bin/sh/builtins/for2.0
new file mode 100644 (file)
index 0000000..2eef5a7
--- /dev/null
@@ -0,0 +1,9 @@
+# $FreeBSD: src/tools/regression/bin/sh/builtins/for2.0,v 1.1 2012/01/22 14:00:33 jilles Exp $
+
+r=x
+f() { return 42; }
+f
+for i in x; do
+       r=$?
+done
+[ "$r" = 42 ]
diff --git a/tools/regression/bin/sh/builtins/for3.0 b/tools/regression/bin/sh/builtins/for3.0
new file mode 100644 (file)
index 0000000..dd0f952
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/tools/regression/bin/sh/builtins/for3.0,v 1.1 2012/01/22 14:00:33 jilles Exp $
+
+r=x
+f() { return 42; }
+for i in x`f`; do
+       r=$?
+done
+[ "$r" = 42 ]