sh: Fix two bugs with case and exit status:
authorPeter Avalos <pavalos@dragonflybsd.org>
Sun, 5 Feb 2012 20:02:44 +0000 (12:02 -0800)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sun, 5 Feb 2012 21:03:59 +0000 (13:03 -0800)
* If no pattern is matched, POSIX says the exit status shall be 0 (even if
  there are command substitutions).
* If a pattern is matched and there are no command substitutions, the first
  command should see the $? from before the case command, not always 0.

Obtained-from:  FreeBSD 230154
(cherry picked from commit c79cd3b3a40bbcea12f869fee83c021fc6c8bf90)

bin/sh/eval.c
tools/regression/bin/sh/builtins/case14.0 [new file with mode: 0644]
tools/regression/bin/sh/builtins/case15.0 [new file with mode: 0644]
tools/regression/bin/sh/builtins/case16.0 [new file with mode: 0644]

index 249505d..dc1385b 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  * @(#)eval.c  8.9 (Berkeley) 6/8/95
- * $FreeBSD: src/bin/sh/eval.c,v 1.115 2011/12/28 22:10:12 jilles Exp $
+ * $FreeBSD: src/bin/sh/eval.c,v 1.116 2012/01/15 20:04:05 jilles Exp $
  */
 
 #include <sys/time.h>
@@ -379,7 +379,6 @@ evalcase(union node *n, int flags)
        setstackmark(&smark);
        arglist.lastp = &arglist.list;
        oexitstatus = exitstatus;
-       exitstatus = 0;
        expandarg(n->ncase.expr, &arglist, EXP_TILDE);
        for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) {
                for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
@@ -393,11 +392,14 @@ evalcase(union node *n, int flags)
                                                return (NULL);
                                        cp = cp->nclist.next;
                                }
+                               if (cp->nclist.body == NULL)
+                                       exitstatus = 0;
                                return (cp->nclist.body);
                        }
                }
        }
        popstackmark(&smark);
+       exitstatus = 0;
        return (NULL);
 }
 
diff --git a/tools/regression/bin/sh/builtins/case14.0 b/tools/regression/bin/sh/builtins/case14.0
new file mode 100644 (file)
index 0000000..f2dc336
--- /dev/null
@@ -0,0 +1,5 @@
+# $FreeBSD: src/tools/regression/bin/sh/builtins/case14.0,v 1.1 2012/01/15 20:04:05 jilles Exp $
+
+case `false` in
+no) exit 3 ;;
+esac
diff --git a/tools/regression/bin/sh/builtins/case15.0 b/tools/regression/bin/sh/builtins/case15.0
new file mode 100644 (file)
index 0000000..f7ee26f
--- /dev/null
@@ -0,0 +1,5 @@
+# $FreeBSD: src/tools/regression/bin/sh/builtins/case15.0,v 1.1 2012/01/15 20:04:05 jilles Exp $
+
+case x in
+`false`) exit 3 ;;
+esac
diff --git a/tools/regression/bin/sh/builtins/case16.0 b/tools/regression/bin/sh/builtins/case16.0
new file mode 100644 (file)
index 0000000..4cb6cf3
--- /dev/null
@@ -0,0 +1,7 @@
+# $FreeBSD: src/tools/regression/bin/sh/builtins/case16.0,v 1.1 2012/01/15 20:04:05 jilles Exp $
+
+f() { return 42; }
+f
+case x in
+x) [ $? = 42 ] ;;
+esac