sh: Reduce unnecessary forks with eval.
[dragonfly.git] / bin / sh / eval.c
index 1bf6a0a..ecc53f4 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  * @(#)eval.c  8.9 (Berkeley) 6/8/95
- * $FreeBSD: src/bin/sh/eval.c,v 1.108 2011/06/09 23:12:23 jilles Exp $
+ * $FreeBSD: src/bin/sh/eval.c,v 1.110 2011/06/16 21:50:28 jilles Exp $
  */
 
 #include <sys/time.h>
@@ -141,7 +141,7 @@ evalcmd(int argc, char **argv)
                         STPUTC('\0', concat);
                         p = grabstackstr(concat);
                 }
-                evalstring(p, builtin_flags & EV_TESTED);
+                evalstring(p, builtin_flags);
         } else
                 exitstatus = 0;
         return exitstatus;
@@ -573,14 +573,8 @@ evalpipe(union node *n)
 static int
 is_valid_fast_cmdsubst(union node *n)
 {
-       union node *argp;
 
-       if (n->type != NCMD)
-               return 0;
-       for (argp = n->ncmd.args ; argp ; argp = argp->narg.next)
-               if (expandhassideeffects(argp->narg.text))
-                       return 0;
-       return 1;
+       return (n->type == NCMD);
 }
 
 /*
@@ -598,6 +592,7 @@ evalbackcmd(union node *n, struct backcmd *result)
        struct stackmark smark;         /* unnecessary */
        struct jmploc jmploc;
        struct jmploc *savehandler;
+       struct localvar *savelocalvars;
 
        setstackmark(&smark);
        result->fd = -1;
@@ -610,12 +605,18 @@ evalbackcmd(union node *n, struct backcmd *result)
        }
        if (is_valid_fast_cmdsubst(n)) {
                exitstatus = oexitstatus;
+               savelocalvars = localvars;
+               localvars = NULL;
+               forcelocal++;
                savehandler = handler;
                if (setjmp(jmploc.loc)) {
                        if (exception == EXERROR || exception == EXEXEC)
                                exitstatus = 2;
                        else if (exception != 0) {
                                handler = savehandler;
+                               forcelocal--;
+                               poplocalvars();
+                               localvars = savelocalvars;
                                longjmp(handler->loc, 1);
                        }
                } else {
@@ -623,6 +624,9 @@ evalbackcmd(union node *n, struct backcmd *result)
                        evalcommand(n, EV_BACKCMD, result);
                }
                handler = savehandler;
+               forcelocal--;
+               poplocalvars();
+               localvars = savelocalvars;
        } else {
                exitstatus = 0;
                if (pipe(pip) < 0)
@@ -907,6 +911,7 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
                                dup2(pip[1], 1);
                                close(pip[1]);
                        }
+                       flags &= ~EV_BACKCMD;
                }
                flags |= EV_EXIT;
        }