mirror of
git://slackware.nl/current.git
synced 2025-02-14 08:48:37 +01:00
844 lines
20 KiB
Diff
844 lines
20 KiB
Diff
![]() |
diff -urN netbsd-sh/builtins.def ash-0.3.7.orig/builtins.def
|
||
|
--- netbsd-sh/builtins.def Mon Apr 10 13:02:58 2000
|
||
|
+++ ash-0.3.7.orig/builtins.def Mon Apr 23 22:16:46 2001
|
||
|
@@ -49,12 +49,13 @@
|
||
|
#
|
||
|
# NOTE: bltincmd must come first!
|
||
|
|
||
|
-bltincmd command
|
||
|
+bltincmd builtin
|
||
|
#alloccmd alloc
|
||
|
bgcmd -j bg
|
||
|
breakcmd break continue
|
||
|
#catfcmd catf
|
||
|
cdcmd cd chdir
|
||
|
+commandcmd command
|
||
|
dotcmd .
|
||
|
echocmd echo
|
||
|
evalcmd eval
|
||
|
diff -urN netbsd-sh/eval.c ash-0.3.7.orig/eval.c
|
||
|
--- netbsd-sh/eval.c Tue May 23 12:03:18 2000
|
||
|
+++ ash-0.3.7.orig/eval.c Mon Apr 23 22:16:46 2001
|
||
|
@@ -45,7 +45,9 @@
|
||
|
#endif
|
||
|
#endif /* not lint */
|
||
|
|
||
|
+#include <sys/types.h>
|
||
|
#include <signal.h>
|
||
|
+#include <malloc.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
/*
|
||
|
@@ -101,6 +103,8 @@
|
||
|
STATIC void evalpipe __P((union node *));
|
||
|
STATIC void evalcommand __P((union node *, int, struct backcmd *));
|
||
|
STATIC void prehash __P((union node *));
|
||
|
+STATIC int is_assignment_builtin __P((const char *));
|
||
|
+STATIC const char *get_standard_path __P((void));
|
||
|
|
||
|
|
||
|
/*
|
||
|
@@ -257,6 +261,11 @@
|
||
|
evalcase(n, flags);
|
||
|
break;
|
||
|
case NDEFUN:
|
||
|
+ if (is_special_builtin(n->narg.text)) {
|
||
|
+ outfmt(out2, "%s is a special built-in\n", n->narg.text);
|
||
|
+ exitstatus = 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
defun(n->narg.text, n->narg.next);
|
||
|
exitstatus = 0;
|
||
|
break;
|
||
|
@@ -497,9 +507,14 @@
|
||
|
close(0);
|
||
|
copyfd(prevfd, 0);
|
||
|
close(prevfd);
|
||
|
+ if (pip[0] == 0) {
|
||
|
+ pip[0] = -1;
|
||
|
+ }
|
||
|
}
|
||
|
if (pip[1] >= 0) {
|
||
|
- close(pip[0]);
|
||
|
+ if (pip[0] >= 0) {
|
||
|
+ close(pip[0]);
|
||
|
+ }
|
||
|
if (pip[1] != 1) {
|
||
|
close(1);
|
||
|
copyfd(pip[1], 1);
|
||
|
@@ -607,6 +622,7 @@
|
||
|
int argc;
|
||
|
char **envp;
|
||
|
int varflag;
|
||
|
+ int pseudovarflag;
|
||
|
struct strlist *sp;
|
||
|
int mode;
|
||
|
int pip[2];
|
||
|
@@ -619,12 +635,17 @@
|
||
|
struct localvar *volatile savelocalvars;
|
||
|
volatile int e;
|
||
|
char *lastarg;
|
||
|
+ int not_special;
|
||
|
+ const char *path;
|
||
|
+ const char *standard_path;
|
||
|
#if __GNUC__
|
||
|
/* Avoid longjmp clobbering */
|
||
|
(void) &argv;
|
||
|
(void) &argc;
|
||
|
(void) &lastarg;
|
||
|
(void) &flags;
|
||
|
+ (void) ¬_special;
|
||
|
+ (void) &standard_path;
|
||
|
#endif
|
||
|
|
||
|
/* First expand the arguments. */
|
||
|
@@ -632,21 +653,31 @@
|
||
|
setstackmark(&smark);
|
||
|
arglist.lastp = &arglist.list;
|
||
|
varlist.lastp = &varlist.list;
|
||
|
+ arglist.list = 0;
|
||
|
varflag = 1;
|
||
|
+ pseudovarflag = 0;
|
||
|
oexitstatus = exitstatus;
|
||
|
exitstatus = 0;
|
||
|
+ not_special = 0;
|
||
|
+ path = pathval();
|
||
|
+ standard_path = NULL;
|
||
|
for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
|
||
|
char *p = argp->narg.text;
|
||
|
- if (varflag && is_name(*p)) {
|
||
|
+ if ((varflag || pseudovarflag) && is_name(*p)) {
|
||
|
do {
|
||
|
p++;
|
||
|
} while (is_in_name(*p));
|
||
|
if (*p == '=') {
|
||
|
- expandarg(argp, &varlist, EXP_VARTILDE);
|
||
|
+ if (varflag)
|
||
|
+ expandarg(argp, &varlist, EXP_VARTILDE);
|
||
|
+ else
|
||
|
+ expandarg(argp, &arglist, EXP_VARTILDE);
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
|
||
|
+ if (varflag && arglist.list && is_assignment_builtin(arglist.list->text))
|
||
|
+ pseudovarflag = 1;
|
||
|
varflag = 0;
|
||
|
}
|
||
|
*arglist.lastp = NULL;
|
||
|
@@ -688,37 +719,75 @@
|
||
|
cmdentry.u.index = BLTINCMD;
|
||
|
} else {
|
||
|
static const char PATH[] = "PATH=";
|
||
|
- const char *path = pathval();
|
||
|
+ const char *oldpath = NULL;
|
||
|
+ int findflag = DO_ERR;
|
||
|
|
||
|
/*
|
||
|
* Modify the command lookup path, if a PATH= assignment
|
||
|
* is present
|
||
|
*/
|
||
|
for (sp = varlist.list ; sp ; sp = sp->next)
|
||
|
- if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0)
|
||
|
+ if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
|
||
|
path = sp->text + sizeof(PATH) - 1;
|
||
|
-
|
||
|
- find_command(argv[0], &cmdentry, DO_ERR, path);
|
||
|
- if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
|
||
|
- exitstatus = 127;
|
||
|
- flushout(&errout);
|
||
|
- return;
|
||
|
- }
|
||
|
- /* implement the bltin builtin here */
|
||
|
- if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == BLTINCMD) {
|
||
|
- for (;;) {
|
||
|
+ findflag |= DO_BRUTE;
|
||
|
+ }
|
||
|
+ for(;;) {
|
||
|
+ find_command(argv[0], &cmdentry, findflag, path);
|
||
|
+ if (oldpath) {
|
||
|
+ path = oldpath;
|
||
|
+ oldpath = NULL;
|
||
|
+ }
|
||
|
+ if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
|
||
|
+ exitstatus = 127;
|
||
|
+ flushout(&errout);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ /* implement the bltin builtin here */
|
||
|
+ if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == BLTINCMD) {
|
||
|
+ not_special = 1;
|
||
|
+ for(;;) {
|
||
|
+ argv++;
|
||
|
+ if (--argc == 0)
|
||
|
+ break;
|
||
|
+ if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
|
||
|
+ outfmt(&errout, "%s: not found\n", *argv);
|
||
|
+ exitstatus = 127;
|
||
|
+ flushout(&errout);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ if (cmdentry.u.index != BLTINCMD)
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == COMMANDCMD) {
|
||
|
+ not_special = 1;
|
||
|
argv++;
|
||
|
- if (--argc == 0)
|
||
|
- break;
|
||
|
- if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
|
||
|
- outfmt(&errout, "%s: not found\n", *argv);
|
||
|
- exitstatus = 127;
|
||
|
- flushout(&errout);
|
||
|
- return;
|
||
|
+ if (--argc == 0) {
|
||
|
+ exitstatus = 0;
|
||
|
+ goto out;
|
||
|
}
|
||
|
- if (cmdentry.u.index != BLTINCMD)
|
||
|
- break;
|
||
|
+ if (*argv[0] == '-') {
|
||
|
+ if (!equal(argv[0], "-p")) {
|
||
|
+ argv--;
|
||
|
+ argc++;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ argv++;
|
||
|
+ if (--argc == 0) {
|
||
|
+ exitstatus = 0;
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ if (!standard_path) {
|
||
|
+ standard_path = get_standard_path();
|
||
|
+ }
|
||
|
+ oldpath = path;
|
||
|
+ path = standard_path;
|
||
|
+ findflag |= DO_BRUTE;
|
||
|
+ }
|
||
|
+ findflag |= DO_NOFUN;
|
||
|
+ continue;
|
||
|
}
|
||
|
+ break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -756,13 +825,12 @@
|
||
|
#ifdef DEBUG
|
||
|
trputs("Shell function: "); trargs(argv);
|
||
|
#endif
|
||
|
+ exitstatus = oexitstatus;
|
||
|
redirect(cmd->ncmd.redirect, REDIR_PUSH);
|
||
|
saveparam = shellparam;
|
||
|
shellparam.malloc = 0;
|
||
|
- shellparam.reset = 1;
|
||
|
shellparam.nparam = argc - 1;
|
||
|
shellparam.p = argv + 1;
|
||
|
- shellparam.optnext = NULL;
|
||
|
INTOFF;
|
||
|
savelocalvars = localvars;
|
||
|
localvars = NULL;
|
||
|
@@ -772,6 +840,8 @@
|
||
|
freeparam((volatile struct shparam *)
|
||
|
&saveparam);
|
||
|
} else {
|
||
|
+ saveparam.optind = shellparam.optind;
|
||
|
+ saveparam.optoff = shellparam.optoff;
|
||
|
freeparam(&shellparam);
|
||
|
shellparam = saveparam;
|
||
|
}
|
||
|
@@ -790,6 +860,8 @@
|
||
|
INTOFF;
|
||
|
poplocalvars();
|
||
|
localvars = savelocalvars;
|
||
|
+ saveparam.optind = shellparam.optind;
|
||
|
+ saveparam.optoff = shellparam.optoff;
|
||
|
freeparam(&shellparam);
|
||
|
shellparam = saveparam;
|
||
|
handler = savehandler;
|
||
|
@@ -832,6 +908,8 @@
|
||
|
out1 = &output;
|
||
|
out2 = &errout;
|
||
|
freestdout();
|
||
|
+ if (!not_special && is_special_builtin(commandname))
|
||
|
+ listsetvar(cmdenviron);
|
||
|
cmdenviron = NULL;
|
||
|
if (e != EXSHELLPROC) {
|
||
|
commandname = savecmdname;
|
||
|
@@ -867,7 +953,7 @@
|
||
|
for (sp = varlist.list ; sp ; sp = sp->next)
|
||
|
setvareq(sp->text, VEXPORT|VSTACK);
|
||
|
envp = environment();
|
||
|
- shellexec(argv, envp, pathval(), cmdentry.u.index);
|
||
|
+ shellexec(argv, envp, path, cmdentry.u.index);
|
||
|
}
|
||
|
goto out;
|
||
|
|
||
|
@@ -1025,4 +1111,49 @@
|
||
|
shellexec(argv + 1, environment(), pathval(), 0);
|
||
|
}
|
||
|
return 0;
|
||
|
+}
|
||
|
+
|
||
|
+STATIC int
|
||
|
+is_assignment_builtin (command)
|
||
|
+ const char *command;
|
||
|
+{
|
||
|
+ static const char *assignment_builtins[] = {
|
||
|
+ "alias", "declare", "export", "local", "readonly", "typeset",
|
||
|
+ (char *)NULL
|
||
|
+ };
|
||
|
+ int i;
|
||
|
+
|
||
|
+ for (i = 0; assignment_builtins[i]; i++)
|
||
|
+ if (strcmp(command, assignment_builtins[i]) == 0) return 1;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+is_special_builtin(name)
|
||
|
+ const char *name;
|
||
|
+{
|
||
|
+ static const char *special_builtins[] = {
|
||
|
+ "break", ":", ".", "continue", "eval", "exec", "exit",
|
||
|
+ "export", "readonly", "return", "set", "shift", "times",
|
||
|
+ "trap", "unset", (char *)NULL
|
||
|
+ };
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if (!name) return 0;
|
||
|
+ for (i = 0; special_builtins[i]; i++)
|
||
|
+ if (equal(name, special_builtins[i])) return 1;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+STATIC const char *
|
||
|
+get_standard_path()
|
||
|
+{
|
||
|
+ char *p;
|
||
|
+ size_t len;
|
||
|
+
|
||
|
+ len = confstr(_CS_PATH, NULL, 0);
|
||
|
+ p = stalloc(len + 2);
|
||
|
+ *p = '\0';
|
||
|
+ confstr(_CS_PATH, p, len);
|
||
|
+ return p;
|
||
|
}
|
||
|
diff -urN netbsd-sh/eval.h ash-0.3.7.orig/eval.h
|
||
|
--- netbsd-sh/eval.h Fri Jan 28 13:03:00 2000
|
||
|
+++ ash-0.3.7.orig/eval.h Mon Apr 23 22:16:46 2001
|
||
|
@@ -61,6 +61,7 @@
|
||
|
int falsecmd __P((int, char **));
|
||
|
int truecmd __P((int, char **));
|
||
|
int execcmd __P((int, char **));
|
||
|
+int is_special_builtin __P((const char *));
|
||
|
|
||
|
/* in_function returns nonzero if we are currently evaluating a function */
|
||
|
#define in_function() funcnest
|
||
|
diff -urN netbsd-sh/exec.c ash-0.3.7.orig/exec.c
|
||
|
--- netbsd-sh/exec.c Fri Jan 12 17:50:35 2001
|
||
|
+++ ash-0.3.7.orig/exec.c Mon Apr 23 22:16:46 2001
|
||
|
@@ -51,6 +51,7 @@
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
#include <stdlib.h>
|
||
|
+#include <sysexits.h>
|
||
|
|
||
|
/*
|
||
|
* When commands are first encountered, they are entered in a hash table.
|
||
|
@@ -108,6 +109,9 @@
|
||
|
STATIC void clearcmdentry __P((int));
|
||
|
STATIC struct tblentry *cmdlookup __P((char *, int));
|
||
|
STATIC void delete_cmd_entry __P((void));
|
||
|
+STATIC int describe_command __P((char *, int));
|
||
|
+STATIC int path_change __P((const char *, int *));
|
||
|
+STATIC int is_regular_builtin __P((const char *));
|
||
|
|
||
|
|
||
|
|
||
|
@@ -164,7 +172,7 @@
|
||
|
char **envp;
|
||
|
{
|
||
|
int e;
|
||
|
-#ifndef BSD
|
||
|
+#if !defined(BSD) && !defined(linux)
|
||
|
char *p;
|
||
|
#endif
|
||
|
|
||
|
@@ -180,7 +188,7 @@
|
||
|
initshellproc();
|
||
|
setinputfile(cmd, 0);
|
||
|
commandname = arg0 = savestr(argv[0]);
|
||
|
-#ifndef BSD
|
||
|
+#if !defined(BSD) && !defined(linux)
|
||
|
pgetc(); pungetc(); /* fill up input buffer */
|
||
|
p = parsenextc;
|
||
|
if (parsenleft > 2 && p[0] == '#' && p[1] == '!') {
|
||
|
@@ -195,7 +203,7 @@
|
||
|
}
|
||
|
|
||
|
|
||
|
-#ifndef BSD
|
||
|
+#if !defined(BSD) && !defined(linux)
|
||
|
/*
|
||
|
* Execute an interpreter introduced by "#!", for systems where this
|
||
|
* feature has not been built into the kernel. If the interpreter is
|
||
|
@@ -351,27 +359,29 @@
|
||
|
if (*argptr == NULL) {
|
||
|
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
|
||
|
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
|
||
|
- printentry(cmdp, verbose);
|
||
|
+ if (cmdp->cmdtype != CMDBUILTIN) {
|
||
|
+ printentry(cmdp, verbose);
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
+ c = 0;
|
||
|
while ((name = *argptr) != NULL) {
|
||
|
if ((cmdp = cmdlookup(name, 0)) != NULL
|
||
|
&& (cmdp->cmdtype == CMDNORMAL
|
||
|
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
|
||
|
delete_cmd_entry();
|
||
|
find_command(name, &entry, DO_ERR, pathval());
|
||
|
- if (verbose) {
|
||
|
- if (entry.cmdtype != CMDUNKNOWN) { /* if no error msg */
|
||
|
- cmdp = cmdlookup(name, 0);
|
||
|
- printentry(cmdp, verbose);
|
||
|
- }
|
||
|
+ if (entry.cmdtype == CMDUNKNOWN) c = 1;
|
||
|
+ else if (verbose) {
|
||
|
+ cmdp = cmdlookup(name, 0);
|
||
|
+ if (cmdp) printentry(cmdp, verbose);
|
||
|
flushall();
|
||
|
}
|
||
|
argptr++;
|
||
|
}
|
||
|
- return 0;
|
||
|
+ return c;
|
||
|
}
|
||
|
|
||
|
|
||
|
@@ -435,6 +445,10 @@
|
||
|
struct stat statb;
|
||
|
int e;
|
||
|
int i;
|
||
|
+ int bltin;
|
||
|
+ int firstchange;
|
||
|
+ int updatetbl;
|
||
|
+ int regular;
|
||
|
|
||
|
/* If name contains a slash, don't use the hash table */
|
||
|
if (strchr(name, '/') != NULL) {
|
||
|
@@ -459,12 +473,54 @@
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+ updatetbl = 1;
|
||
|
+ if (act & DO_BRUTE) {
|
||
|
+ firstchange = path_change(path, &bltin);
|
||
|
+ } else {
|
||
|
+ bltin = builtinloc;
|
||
|
+ firstchange = 9999;
|
||
|
+ }
|
||
|
+
|
||
|
/* If name is in the table, and not invalidated by cd, we're done */
|
||
|
- if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0)
|
||
|
- goto success;
|
||
|
+ if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
|
||
|
+ if (cmdp->cmdtype == CMDFUNCTION) {
|
||
|
+ if (act & DO_NOFUN) {
|
||
|
+ updatetbl = 0;
|
||
|
+ } else {
|
||
|
+ goto success;
|
||
|
+ }
|
||
|
+ } else if (act & DO_BRUTE) {
|
||
|
+ if ((cmdp->cmdtype == CMDNORMAL &&
|
||
|
+ cmdp->param.index >= firstchange) ||
|
||
|
+ (cmdp->cmdtype == CMDBUILTIN &&
|
||
|
+ ((builtinloc < 0 && bltin >= 0) ?
|
||
|
+ bltin : builtinloc) >= firstchange)) {
|
||
|
+ /* need to recompute the entry */
|
||
|
+ } else {
|
||
|
+ goto success;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ goto success;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((regular = is_regular_builtin(name))) {
|
||
|
+ if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
|
||
|
+ goto success;
|
||
|
+ }
|
||
|
+ } else if (act & DO_BRUTE) {
|
||
|
+ if (firstchange == 0) {
|
||
|
+ updatetbl = 0;
|
||
|
+ }
|
||
|
+ }
|
||
|
|
||
|
/* If %builtin not in path, check for builtin next */
|
||
|
- if (builtinloc < 0 && (i = find_builtin(name)) >= 0) {
|
||
|
+ if ((bltin < 0 || regular) && (i = find_builtin(name)) >= 0) {
|
||
|
+ if (!updatetbl) {
|
||
|
+ entry->cmdtype = CMDBUILTIN;
|
||
|
+ entry->u.index = i;
|
||
|
+ return;
|
||
|
+ }
|
||
|
INTOFF;
|
||
|
cmdp = cmdlookup(name, 1);
|
||
|
cmdp->cmdtype = CMDBUILTIN;
|
||
|
@@ -475,7 +531,7 @@
|
||
|
|
||
|
/* We have to search path. */
|
||
|
prev = -1; /* where to start */
|
||
|
- if (cmdp) { /* doing a rehash */
|
||
|
+ if (cmdp && cmdp->rehash) { /* doing a rehash */
|
||
|
if (cmdp->cmdtype == CMDBUILTIN)
|
||
|
prev = builtinloc;
|
||
|
else
|
||
|
@@ -488,26 +544,38 @@
|
||
|
while ((fullname = padvance(&path, name)) != NULL) {
|
||
|
stunalloc(fullname);
|
||
|
idx++;
|
||
|
+ if (idx >= firstchange) {
|
||
|
+ updatetbl = 0;
|
||
|
+ }
|
||
|
if (pathopt) {
|
||
|
if (prefix("builtin", pathopt)) {
|
||
|
- if ((i = find_builtin(name)) < 0)
|
||
|
- goto loop;
|
||
|
- INTOFF;
|
||
|
- cmdp = cmdlookup(name, 1);
|
||
|
- cmdp->cmdtype = CMDBUILTIN;
|
||
|
- cmdp->param.index = i;
|
||
|
- INTON;
|
||
|
- goto success;
|
||
|
- } else if (prefix("func", pathopt)) {
|
||
|
+ if ((i = find_builtin(name)) >= 0) {
|
||
|
+ if (!updatetbl) {
|
||
|
+ entry->cmdtype = CMDBUILTIN;
|
||
|
+ entry->u.index = i;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ INTOFF;
|
||
|
+ cmdp = cmdlookup(name, 1);
|
||
|
+ cmdp->cmdtype = CMDBUILTIN;
|
||
|
+ cmdp->param.index = i;
|
||
|
+ INTON;
|
||
|
+ goto success;
|
||
|
+ } else {
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ } else if (!(act & DO_NOFUN) &&
|
||
|
+ prefix("func", pathopt)) {
|
||
|
/* handled below */
|
||
|
} else {
|
||
|
- goto loop; /* ignore unimplemented options */
|
||
|
+ continue; /* ignore unimplemented options */
|
||
|
}
|
||
|
}
|
||
|
/* if rehash, don't redo absolute path names */
|
||
|
- if (fullname[0] == '/' && idx <= prev) {
|
||
|
+ if (fullname[0] == '/' && idx <= prev &&
|
||
|
+ idx < firstchange) {
|
||
|
if (idx < prev)
|
||
|
- goto loop;
|
||
|
+ continue;
|
||
|
TRACE(("searchexec \"%s\": no change\n", name));
|
||
|
goto success;
|
||
|
}
|
||
|
@@ -522,7 +590,7 @@
|
||
|
}
|
||
|
e = EACCES; /* if we fail, this will be the error */
|
||
|
if (!S_ISREG(statb.st_mode))
|
||
|
- goto loop;
|
||
|
+ continue;
|
||
|
if (pathopt) { /* this is a %func directory */
|
||
|
stalloc(strlen(fullname) + 1);
|
||
|
readcmdfile(fullname);
|
||
|
@@ -544,6 +612,13 @@
|
||
|
}
|
||
|
#endif
|
||
|
TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
|
||
|
+ /* If we aren't called with DO_BRUTE and cmdp is set, it must
|
||
|
+ be a function and we're being called with DO_NOFUN */
|
||
|
+ if (!updatetbl) {
|
||
|
+ entry->cmdtype = CMDNORMAL;
|
||
|
+ entry->u.index = idx;
|
||
|
+ return;
|
||
|
+ }
|
||
|
INTOFF;
|
||
|
cmdp = cmdlookup(name, 1);
|
||
|
cmdp->cmdtype = CMDNORMAL;
|
||
|
@@ -553,7 +628,7 @@
|
||
|
}
|
||
|
|
||
|
/* We failed. If there was an entry for this command, delete it */
|
||
|
- if (cmdp)
|
||
|
+ if (cmdp && updatetbl)
|
||
|
delete_cmd_entry();
|
||
|
if (act & DO_ERR)
|
||
|
outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));
|
||
|
@@ -618,37 +693,12 @@
|
||
|
changepath(newval)
|
||
|
const char *newval;
|
||
|
{
|
||
|
- const char *old, *new;
|
||
|
- int idx;
|
||
|
int firstchange;
|
||
|
int bltin;
|
||
|
|
||
|
- old = pathval();
|
||
|
- new = newval;
|
||
|
- firstchange = 9999; /* assume no change */
|
||
|
- idx = 0;
|
||
|
- bltin = -1;
|
||
|
- for (;;) {
|
||
|
- if (*old != *new) {
|
||
|
- firstchange = idx;
|
||
|
- if ((*old == '\0' && *new == ':')
|
||
|
- || (*old == ':' && *new == '\0'))
|
||
|
- firstchange++;
|
||
|
- old = new; /* ignore subsequent differences */
|
||
|
- }
|
||
|
- if (*new == '\0')
|
||
|
- break;
|
||
|
- if (*new == '%' && bltin < 0 && prefix("builtin", new + 1))
|
||
|
- bltin = idx;
|
||
|
- if (*new == ':') {
|
||
|
- idx++;
|
||
|
- }
|
||
|
- new++, old++;
|
||
|
- }
|
||
|
+ firstchange = path_change(newval, &bltin);
|
||
|
if (builtinloc < 0 && bltin >= 0)
|
||
|
builtinloc = bltin; /* zap builtins */
|
||
|
- if (builtinloc >= 0 && bltin < 0)
|
||
|
- firstchange = 0;
|
||
|
clearcmdentry(firstchange);
|
||
|
builtinloc = bltin;
|
||
|
}
|
||
|
@@ -838,11 +888,9 @@
|
||
|
{
|
||
|
struct cmdentry entry;
|
||
|
|
||
|
- INTOFF;
|
||
|
entry.cmdtype = CMDFUNCTION;
|
||
|
entry.u.func = copyfunc(func);
|
||
|
addcmdentry(name, &entry);
|
||
|
- INTON;
|
||
|
}
|
||
|
|
||
|
|
||
|
@@ -944,4 +992,190 @@
|
||
|
}
|
||
|
}
|
||
|
return err;
|
||
|
+}
|
||
|
+
|
||
|
+STATIC int
|
||
|
+describe_command(command, verbose)
|
||
|
+ char *command;
|
||
|
+ int verbose;
|
||
|
+{
|
||
|
+ struct cmdentry entry;
|
||
|
+ struct tblentry *cmdp;
|
||
|
+ char **pp;
|
||
|
+ struct alias *ap;
|
||
|
+ extern char *const parsekwd[];
|
||
|
+
|
||
|
+ for (pp = (char **)parsekwd; *pp; pp++)
|
||
|
+ if (**pp == *command && equal(*pp, command))
|
||
|
+ break;
|
||
|
+
|
||
|
+ if (*pp) {
|
||
|
+ if (verbose) {
|
||
|
+ out1fmt("%s is a reserved word\n", command);
|
||
|
+ } else {
|
||
|
+ out1fmt("%s\n", command);
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Then look at the aliases */
|
||
|
+ if ((ap = lookupalias(command, 1)) != NULL) {
|
||
|
+ if (verbose) {
|
||
|
+ out1fmt("%s is aliased to `%s'\n", command, ap->val);
|
||
|
+ } else {
|
||
|
+ out1fmt("alias %s='%s'\n", command, ap->val);
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Then check if it is a tracked alias */
|
||
|
+ if ((cmdp = cmdlookup(command, 0)) != NULL) {
|
||
|
+ entry.cmdtype = cmdp->cmdtype;
|
||
|
+ entry.u = cmdp->param;
|
||
|
+ }
|
||
|
+ else {
|
||
|
+ /* Finally use brute force */
|
||
|
+ find_command(command, &entry, DO_ABS, pathval());
|
||
|
+ }
|
||
|
+
|
||
|
+ switch (entry.cmdtype) {
|
||
|
+ case CMDNORMAL: {
|
||
|
+ int j = entry.u.index;
|
||
|
+ const char *path = pathval();
|
||
|
+ char *name;
|
||
|
+ if (j == -1)
|
||
|
+ name = command;
|
||
|
+ else {
|
||
|
+ do {
|
||
|
+ name = padvance(&path, command);
|
||
|
+ stunalloc(name);
|
||
|
+ } while (--j >= 0);
|
||
|
+ }
|
||
|
+ if (verbose) {
|
||
|
+ out1fmt("%s is %s\n", command, name);
|
||
|
+ } else {
|
||
|
+ out1fmt("%s\n", name);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ case CMDFUNCTION:
|
||
|
+ if (verbose) {
|
||
|
+ out1fmt("%s is a function\n", command);
|
||
|
+ } else {
|
||
|
+ out1fmt("%s\n", command);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case CMDBUILTIN:
|
||
|
+ if (verbose) {
|
||
|
+ if (is_special_builtin(command)) {
|
||
|
+ out1fmt("%s is a special built-in utility\n", command);
|
||
|
+ } else {
|
||
|
+ out1fmt("%s is a built-in utility\n", command);
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ out1fmt("%s\n", command);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ outfmt(out2, "%s not found\n", command);
|
||
|
+ return 127;
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+commandcmd(argc, argv)
|
||
|
+ int argc;
|
||
|
+ char **argv;
|
||
|
+{
|
||
|
+ int c;
|
||
|
+ int default_path = 0;
|
||
|
+ int verify_only = 0;
|
||
|
+ int verbose_verify_only = 0;
|
||
|
+
|
||
|
+ while ((c = nextopt("pvV")) != '\0')
|
||
|
+ switch (c) {
|
||
|
+ case 'p':
|
||
|
+ default_path = 1;
|
||
|
+ break;
|
||
|
+ case 'v':
|
||
|
+ verify_only = 1;
|
||
|
+ break;
|
||
|
+ case 'V':
|
||
|
+ verbose_verify_only = 1;
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ outfmt(out2,
|
||
|
+"command: nextopt returned character code 0%o\n", c);
|
||
|
+ return EX_SOFTWARE;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (default_path + verify_only + verbose_verify_only > 1 ||
|
||
|
+ !*argptr) {
|
||
|
+ outfmt(out2,
|
||
|
+"command [-p] command [arg ...]\n");
|
||
|
+ outfmt(out2,
|
||
|
+"command {-v|-V} command\n");
|
||
|
+ return EX_USAGE;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (verify_only || verbose_verify_only) {
|
||
|
+ return describe_command(*argptr, verbose_verify_only);
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+STATIC int
|
||
|
+path_change(newval, bltin)
|
||
|
+ const char *newval;
|
||
|
+ int *bltin;
|
||
|
+{
|
||
|
+ const char *old, *new;
|
||
|
+ int idx;
|
||
|
+ int firstchange;
|
||
|
+
|
||
|
+ old = pathval();
|
||
|
+ new = newval;
|
||
|
+ firstchange = 9999; /* assume no change */
|
||
|
+ idx = 0;
|
||
|
+ *bltin = -1;
|
||
|
+ for (;;) {
|
||
|
+ if (*old != *new) {
|
||
|
+ firstchange = idx;
|
||
|
+ if ((*old == '\0' && *new == ':')
|
||
|
+ || (*old == ':' && *new == '\0'))
|
||
|
+ firstchange++;
|
||
|
+ old = new; /* ignore subsequent differences */
|
||
|
+ }
|
||
|
+ if (*new == '\0')
|
||
|
+ break;
|
||
|
+ if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1))
|
||
|
+ *bltin = idx;
|
||
|
+ if (*new == ':') {
|
||
|
+ idx++;
|
||
|
+ }
|
||
|
+ new++, old++;
|
||
|
+ }
|
||
|
+ if (builtinloc >= 0 && *bltin < 0)
|
||
|
+ firstchange = 0;
|
||
|
+ return firstchange;
|
||
|
+}
|
||
|
+
|
||
|
+STATIC int
|
||
|
+is_regular_builtin(name)
|
||
|
+ const char *name;
|
||
|
+{
|
||
|
+ static const char *regular_builtins[] = {
|
||
|
+ "alias", "bg", "cd", "command", "false", "fc", "fg",
|
||
|
+ "getopts", "jobs", "kill", "newgrp", "read", "true",
|
||
|
+ "umask", "unalias", "wait", (char *)NULL
|
||
|
+ };
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if (!name) return 0;
|
||
|
+ for (i = 0; regular_builtins[i]; i++)
|
||
|
+ if (equal(name, regular_builtins[i])) return 1;
|
||
|
+ return 0;
|
||
|
}
|
||
|
diff -urN netbsd-sh/exec.h ash-0.3.7.orig/exec.h
|
||
|
--- netbsd-sh/exec.h Tue May 23 12:03:19 2000
|
||
|
+++ ash-0.3.7.orig/exec.h Mon Apr 23 22:16:46 2001
|
||
|
@@ -56,6 +56,8 @@
|
||
|
|
||
|
#define DO_ERR 1 /* find_command prints errors */
|
||
|
#define DO_ABS 2 /* find_command checks absolute paths */
|
||
|
+#define DO_NOFUN 4 /* find_command ignores functions */
|
||
|
+#define DO_BRUTE 8 /* find_command ignores hash table */
|
||
|
|
||
|
extern const char *pathopt; /* set by padvance */
|
||
|
extern int exerrno; /* last exec error */
|
||
|
@@ -74,3 +76,4 @@
|
||
|
void defun __P((char *, union node *));
|
||
|
int unsetfunc __P((char *));
|
||
|
int typecmd __P((int, char **));
|
||
|
+int commandcmd __P((int, char **));
|
||
|
|