diff options
author | stefanf <stefanf@FreeBSD.org> | 2006-04-09 12:21:20 +0000 |
---|---|---|
committer | stefanf <stefanf@FreeBSD.org> | 2006-04-09 12:21:20 +0000 |
commit | 968438f2fcefda39356b35981197656400d90f0f (patch) | |
tree | b2e9e5bfdcae5d9e40672127fa23de6d02ac47ee /bin/sh/eval.c | |
parent | 209025405d1718f956439567f56fb8504bbfc6cf (diff) | |
download | FreeBSD-src-968438f2fcefda39356b35981197656400d90f0f.zip FreeBSD-src-968438f2fcefda39356b35981197656400d90f0f.tar.gz |
Implement some of the differences between special built-ins and other builtins
demanded by POSIX.
- A redirection error is only fatal (meaning the execution of a shell script is
terminated) for special built-ins. Previously it was fatal for all shell
builtins, causing problems like the one reported in PR 88845.
- Variable assignments remain in effect for special built-ins.
- Option or operand errors are only fatal for special built-ins.
This change also makes errors from 'fc' non-fatal (I could not find any reasons
for this behaviour).
Somewhat independently from the above down-grade the error handling in the
shift built-in if the operand is bigger than $# from an error() call (which is
now fatal) to a return 1. I'm not sure if this should be considered a POSIX
"operand error", however this change is needed for now as we trigger that error
while building libncurses. Comparing with other shells, zsh does the same as
our sh before this change (write a diagnostic, return 1), bash behaves as our
sh after this commit (no diagnostic, return 1) and ksh93 and NetBSD's sh treat
it as a fatal error.
Diffstat (limited to 'bin/sh/eval.c')
-rw-r--r-- | bin/sh/eval.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 9d92416..fa2fe59 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -658,8 +658,10 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) /* Now locate the command. */ if (argc == 0) { + /* Variable assignment(s) without command */ cmdentry.cmdtype = CMDBUILTIN; cmdentry.u.index = BLTINCMD; + cmdentry.special = 1; } else { static const char PATH[] = "PATH="; char *path = pathval(); @@ -705,7 +707,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) argv++; if (--argc == 0) break; - if ((cmdentry.u.index = find_builtin(*argv)) < 0) { + if ((cmdentry.u.index = find_builtin(*argv, + &cmdentry.special)) < 0) { outfmt(&errout, "%s: not found\n", *argv); exitstatus = 127; flushout(&errout); @@ -812,7 +815,6 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) memout.bufsize = 64; mode |= REDIR_BACKQ; } - redirect(cmd->ncmd.redirect, mode); savecmdname = commandname; cmdenviron = varlist.list; e = -1; @@ -823,6 +825,9 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) } savehandler = handler; handler = &jmploc; + redirect(cmd->ncmd.redirect, mode); + if (cmdentry.special) + listsetvar(cmdenviron); commandname = argv[0]; argptr = argv + 1; optptr = NULL; /* initialize nextopt */ @@ -842,14 +847,7 @@ cmddone: handler = savehandler; if (e != -1) { if ((e != EXERROR && e != EXEXEC) - || cmdentry.u.index == BLTINCMD - || cmdentry.u.index == DOTCMD - || cmdentry.u.index == EVALCMD -#ifndef NO_HISTORY - || cmdentry.u.index == HISTCMD -#endif - || cmdentry.u.index == EXECCMD - || cmdentry.u.index == COMMANDCMD) + || cmdentry.special) exraise(e); FORCEINTON; } @@ -925,14 +923,12 @@ prehash(union node *n) */ /* - * No command given, or a bltin command with no arguments. Set the - * specified variables. + * No command given, or a bltin command with no arguments. */ int bltincmd(int argc __unused, char **argv __unused) { - listsetvar(cmdenviron); /* * Preserve exitstatus of a previous possible redirection * as POSIX mandates |