diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2010-05-27 15:03:46 +0800 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-05-27 15:03:46 +0800 |
commit | b112dc08c6c86b8b82d60b1169ccab51921241ca (patch) | |
tree | 04bb75f4f823114f566d68ec52745421268baa99 /src/eval.c | |
parent | [REDIR] Move null redirect checks into caller (diff) | |
download | dash-b112dc08c6c86b8b82d60b1169ccab51921241ca.tar.gz dash-b112dc08c6c86b8b82d60b1169ccab51921241ca.zip |
[REDIR] Fix popredir on abnormal exit from built-in
Just like the poplocalvar problem recently fixed, redirections can also be leaked in case of an abnormal exit. This patch fixes it using the same method as poplocalvar, by storing the previous redirection state and restoring to that point. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/src/eval.c b/src/eval.c index 59bded9..d5c1e6c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -219,6 +219,7 @@ evaltree(union node *n, int flags) goto setstatus; case NREDIR: expredir(n->nredir.redirect); + pushredir(n->nredir.redirect); status = redirectsafe(n->nredir.redirect, REDIR_PUSH); if (!status) { evaltree(n->nredir.n, flags & EV_TESTED); @@ -683,6 +684,7 @@ evalcommand(union node *cmd, int flags) #endif { struct localvar_list *localvar_stop; + struct redirtab *redir_stop; struct stackmark smark; union node *argp; struct arglist arglist; @@ -740,6 +742,7 @@ evalcommand(union node *cmd, int flags) preverrout.fd = 2; expredir(cmd->ncmd.redirect); + redir_stop = pushredir(cmd->ncmd.redirect); status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH|REDIR_SAVEFD2); path = vpath.text; @@ -882,6 +885,7 @@ raise: out: if (cmd->ncmd.redirect) popredir(execcmd); + unwindredir(redir_stop); unwindlocalvars(localvar_stop); if (lastarg) /* dsl: I think this is intended to be used to support |