summaryrefslogtreecommitdiffstats
path: root/bin/sh
diff options
context:
space:
mode:
Diffstat (limited to 'bin/sh')
-rw-r--r--bin/sh/eval.c22
-rw-r--r--bin/sh/exec.c15
-rw-r--r--bin/sh/exec.h3
-rw-r--r--bin/sh/options.c2
4 files changed, 23 insertions, 19 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
diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index d983849..85794d9 100644
--- a/bin/sh/exec.c
+++ b/bin/sh/exec.c
@@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
struct tblentry {
struct tblentry *next; /* next entry in hash chain */
union param param; /* definition of builtin function */
+ int special; /* flag for special builtin commands */
short cmdtype; /* index identifying command */
char rehash; /* if set, cd done since entry created */
char cmdname[ARB]; /* name of command */
@@ -317,6 +318,7 @@ find_command(char *name, struct cmdentry *entry, int printerr, char *path)
struct stat statb;
int e;
int i;
+ int spec;
/* If name contains a slash, don't use the hash table */
if (strchr(name, '/') != NULL) {
@@ -330,11 +332,12 @@ find_command(char *name, struct cmdentry *entry, int printerr, char *path)
goto success;
/* If %builtin not in path, check for builtin next */
- if (builtinloc < 0 && (i = find_builtin(name)) >= 0) {
+ if (builtinloc < 0 && (i = find_builtin(name, &spec)) >= 0) {
INTOFF;
cmdp = cmdlookup(name, 1);
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.index = i;
+ cmdp->special = spec;
INTON;
goto success;
}
@@ -356,12 +359,13 @@ loop:
index++;
if (pathopt) {
if (prefix("builtin", pathopt)) {
- if ((i = find_builtin(name)) < 0)
+ if ((i = find_builtin(name, &spec)) < 0)
goto loop;
INTOFF;
cmdp = cmdlookup(name, 1);
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.index = i;
+ cmdp->special = spec;
INTON;
goto success;
} else if (prefix("func", pathopt)) {
@@ -430,6 +434,7 @@ success:
cmdp->rehash = 0;
entry->cmdtype = cmdp->cmdtype;
entry->u = cmdp->param;
+ entry->special = cmdp->special;
}
@@ -439,13 +444,15 @@ success:
*/
int
-find_builtin(char *name)
+find_builtin(char *name, int *special)
{
const struct builtincmd *bp;
for (bp = builtincmd ; bp->name ; bp++) {
- if (*bp->name == *name && equal(bp->name, name))
+ if (*bp->name == *name && equal(bp->name, name)) {
+ *special = bp->special;
return bp->code;
+ }
}
return -1;
}
diff --git a/bin/sh/exec.h b/bin/sh/exec.h
index 429bfda..9f81a6a 100644
--- a/bin/sh/exec.h
+++ b/bin/sh/exec.h
@@ -52,6 +52,7 @@ struct cmdentry {
int index;
union node *func;
} u;
+ int special;
};
@@ -62,7 +63,7 @@ void shellexec(char **, char **, char *, int);
char *padvance(char **, char *);
int hashcmd(int, char **);
void find_command(char *, struct cmdentry *, int, char *);
-int find_builtin(char *);
+int find_builtin(char *, int *);
void hashcd(void);
void changepath(const char *);
void deletefuncs(void);
diff --git a/bin/sh/options.c b/bin/sh/options.c
index 64e129e..58c5c7b 100644
--- a/bin/sh/options.c
+++ b/bin/sh/options.c
@@ -374,7 +374,7 @@ shiftcmd(int argc, char **argv)
if (argc > 1)
n = number(argv[1]);
if (n > shellparam.nparam)
- error("can't shift that many");
+ return 1;
INTOFF;
shellparam.nparam -= n;
for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
OpenPOWER on IntegriCloud