diff options
author | jilles <jilles@FreeBSD.org> | 2010-01-01 18:17:46 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2010-01-01 18:17:46 +0000 |
commit | 446838eef9a2c4d195b487b7b741e56c01af2470 (patch) | |
tree | 6198da26b9a8cb29d4142aca530e1a661605a331 /bin/sh/eval.c | |
parent | 4ce9cced3fd3f56de8a72297d2a0f0939d4bb2f9 (diff) | |
download | FreeBSD-src-446838eef9a2c4d195b487b7b741e56c01af2470.zip FreeBSD-src-446838eef9a2c4d195b487b7b741e56c01af2470.tar.gz |
sh: Fix some bugs with backquoted builtins:
- correctly handle error output in $(builtin 2>&1), clarify out1/out2 vs
output/errout in the code
- treat all builtins as regular builtins so errors do not abort the shell
and variable assignments do not persist
- respect the caller's INTOFF
Some bugs still exist:
- expansion errors may still abort the shell
- some side effects of expansions and builtins persist
Diffstat (limited to 'bin/sh/eval.c')
-rw-r--r-- | bin/sh/eval.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index e54d19a..f2caafb 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -646,7 +646,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) out2str(ps4val()); for (sp = varlist.list ; sp ; sp = sp->next) { if (sep != 0) - outc(' ', &errout); + out2c(' '); p = sp->text; while (*p != '=' && *p != '\0') out2c(*p++); @@ -658,7 +658,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) } for (sp = arglist.list ; sp ; sp = sp->next) { if (sep != 0) - outc(' ', &errout); + out2c(' '); /* Disambiguate command looking like assignment. */ if (sp == arglist.list && strchr(sp->text, '=') != NULL && @@ -670,7 +670,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) out2qstr(sp->text); sep = ' '; } - outc('\n', &errout); + out2c('\n'); flushout(&errout); } @@ -722,9 +722,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) break; if ((cmdentry.u.index = find_builtin(*argv, &cmdentry.special)) < 0) { - outfmt(&errout, "%s: not found\n", *argv); + out2fmt_flush("%s: not found\n", *argv); exitstatus = 127; - flushout(&errout); return; } if (cmdentry.u.index != BLTINCMD) @@ -832,6 +831,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) memout.nextc = memout.buf; memout.bufsize = 64; mode |= REDIR_BACKQ; + cmdentry.special = 0; } savecmdname = commandname; savetopfile = getcurrentfile(); @@ -865,20 +865,21 @@ cmddone: } } handler = savehandler; + if (flags == EV_BACKCMD) { + backcmd->buf = memout.buf; + backcmd->nleft = memout.nextc - memout.buf; + memout.buf = NULL; + } if (e != -1) { if ((e != EXERROR && e != EXEXEC) || cmdentry.special) exraise(e); popfilesupto(savetopfile); - FORCEINTON; + if (flags != EV_BACKCMD) + FORCEINTON; } if (cmdentry.u.index != EXECCMD) popredir(); - if (flags == EV_BACKCMD) { - backcmd->buf = memout.buf; - backcmd->nleft = memout.nextc - memout.buf; - memout.buf = NULL; - } } else { #ifdef DEBUG trputs("normal command: "); trargs(argv); |