diff options
author | jilles <jilles@FreeBSD.org> | 2011-06-12 23:06:04 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2011-06-12 23:06:04 +0000 |
commit | 91789615b49a87147298eee12c9b111d8c1b64c9 (patch) | |
tree | b1cbd950b159dbb3fa6211ba5a7f7fb7709a612e /bin/sh/eval.c | |
parent | 5f2600c6a978923a3904716ce73814baca63fd0f (diff) | |
download | FreeBSD-src-91789615b49a87147298eee12c9b111d8c1b64c9.zip FreeBSD-src-91789615b49a87147298eee12c9b111d8c1b64c9.tar.gz |
sh: Save/restore changed variables in optimized command substitution.
In optimized command substitution, save and restore any variables changed by
expansions (${var=value} and $((var=assigned))), instead of trying to
determine if an expansion may cause such changes.
If $! is referenced in optimized command substitution, do not cause jobs to
be remembered longer.
This fixes $(jobs $!) again, simplifies the man page and shortens the code.
Diffstat (limited to 'bin/sh/eval.c')
-rw-r--r-- | bin/sh/eval.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 92a18e4..9d67b9e 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -571,14 +571,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); } /* @@ -596,6 +590,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; @@ -608,12 +603,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 { @@ -621,6 +622,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) |