]> git.pld-linux.org Git - packages/ash.git/blob - ash-builtin.patch
- dropped pre-cvs changelog
[packages/ash.git] / ash-builtin.patch
1 diff -urN netbsd-sh/builtins.def ash-0.3.7.orig/builtins.def
2 --- netbsd-sh/builtins.def      Mon Apr 10 13:02:58 2000
3 +++ ash-0.3.7.orig/builtins.def Mon Apr 23 22:16:46 2001
4 @@ -49,12 +49,13 @@
5  #
6  # NOTE: bltincmd must come first!
7  
8 -bltincmd       command
9 +bltincmd       builtin
10  #alloccmd      alloc
11  bgcmd -j       bg
12  breakcmd       break continue
13  #catfcmd       catf
14  cdcmd          cd chdir
15 +commandcmd     command
16  dotcmd         .
17  echocmd                echo
18  evalcmd                eval
19 diff -urN netbsd-sh/eval.c ash-0.3.7.orig/eval.c
20 --- netbsd-sh/eval.c    Tue May 23 12:03:18 2000
21 +++ ash-0.3.7.orig/eval.c       Mon Apr 23 22:16:46 2001
22 @@ -45,7 +45,9 @@
23  #endif
24  #endif /* not lint */
25  
26 +#include <sys/types.h>
27  #include <signal.h>
28 +#include <malloc.h>
29  #include <unistd.h>
30  
31  /*
32 @@ -101,6 +103,8 @@
33  STATIC void evalpipe __P((union node *));
34  STATIC void evalcommand __P((union node *, int, struct backcmd *));
35  STATIC void prehash __P((union node *));
36 +STATIC int is_assignment_builtin __P((const char *));
37 +STATIC const char *get_standard_path __P((void));
38  
39  
40  /*
41 @@ -257,6 +261,11 @@
42                 evalcase(n, flags);
43                 break;
44         case NDEFUN:
45 +               if (is_special_builtin(n->narg.text)) {
46 +                       outfmt(out2, "%s is a special built-in\n", n->narg.text);
47 +                       exitstatus = 1;
48 +                       break;
49 +               }
50                 defun(n->narg.text, n->narg.next);
51                 exitstatus = 0;
52                 break;
53 @@ -497,9 +507,14 @@
54                                 close(0);
55                                 copyfd(prevfd, 0);
56                                 close(prevfd);
57 +                               if (pip[0] == 0) {
58 +                                       pip[0] = -1;
59 +                               }
60                         }
61                         if (pip[1] >= 0) {
62 -                               close(pip[0]);
63 +                               if (pip[0] >= 0) {
64 +                                       close(pip[0]);
65 +                               }
66                                 if (pip[1] != 1) {
67                                         close(1);
68                                         copyfd(pip[1], 1);
69 @@ -607,6 +622,7 @@
70         int argc;
71         char **envp;
72         int varflag;
73 +       int pseudovarflag;
74         struct strlist *sp;
75         int mode;
76         int pip[2];
77 @@ -619,12 +635,17 @@
78         struct localvar *volatile savelocalvars;
79         volatile int e;
80         char *lastarg;
81 +       int not_special;
82 +       const char *path;
83 +       const char *standard_path;
84  #if __GNUC__
85         /* Avoid longjmp clobbering */
86         (void) &argv;
87         (void) &argc;
88         (void) &lastarg;
89         (void) &flags;
90 +       (void) &not_special;
91 +       (void) &standard_path;
92  #endif
93  
94         /* First expand the arguments. */
95 @@ -632,21 +653,31 @@
96         setstackmark(&smark);
97         arglist.lastp = &arglist.list;
98         varlist.lastp = &varlist.list;
99 +       arglist.list = 0;
100         varflag = 1;
101 +       pseudovarflag = 0;
102         oexitstatus = exitstatus;
103         exitstatus = 0;
104 +       not_special = 0;
105 +       path = pathval();
106 +       standard_path = NULL;
107         for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
108                 char *p = argp->narg.text;
109 -               if (varflag && is_name(*p)) {
110 +               if ((varflag || pseudovarflag) && is_name(*p)) {
111                         do {
112                                 p++;
113                         } while (is_in_name(*p));
114                         if (*p == '=') {
115 -                               expandarg(argp, &varlist, EXP_VARTILDE);
116 +                               if (varflag)
117 +                                       expandarg(argp, &varlist, EXP_VARTILDE);
118 +                               else
119 +                                       expandarg(argp, &arglist, EXP_VARTILDE);
120                                 continue;
121                         }
122                 }
123                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
124 +               if (varflag && arglist.list && is_assignment_builtin(arglist.list->text))
125 +                       pseudovarflag = 1;
126                 varflag = 0;
127         }
128         *arglist.lastp = NULL;
129 @@ -688,37 +719,75 @@
130                 cmdentry.u.index = BLTINCMD;
131         } else {
132                 static const char PATH[] = "PATH=";
133 -               const char *path = pathval();
134 +               const char *oldpath = NULL;
135 +               int findflag = DO_ERR;
136  
137                 /*
138                  * Modify the command lookup path, if a PATH= assignment
139                  * is present
140                  */
141                 for (sp = varlist.list ; sp ; sp = sp->next)
142 -                       if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0)
143 +                       if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
144                                 path = sp->text + sizeof(PATH) - 1;
145 -
146 -               find_command(argv[0], &cmdentry, DO_ERR, path);
147 -               if (cmdentry.cmdtype == CMDUNKNOWN) {   /* command not found */
148 -                       exitstatus = 127;
149 -                       flushout(&errout);
150 -                       return;
151 -               }
152 -               /* implement the bltin builtin here */
153 -               if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == BLTINCMD) {
154 -                       for (;;) {
155 +                               findflag |= DO_BRUTE;
156 +                       }
157 +               for(;;) {
158 +                       find_command(argv[0], &cmdentry, findflag, path);
159 +                       if (oldpath) {
160 +                               path = oldpath;
161 +                               oldpath = NULL;
162 +                       }
163 +                       if (cmdentry.cmdtype == CMDUNKNOWN) {   /* command not found */
164 +                               exitstatus = 127;
165 +                               flushout(&errout);
166 +                               goto out;
167 +                       }
168 +                       /* implement the bltin builtin here */
169 +                       if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == BLTINCMD) {
170 +                               not_special = 1;
171 +                               for(;;) {
172 +                                       argv++;
173 +                                       if (--argc == 0)
174 +                                               break;
175 +                                       if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
176 +                                               outfmt(&errout, "%s: not found\n", *argv);
177 +                                               exitstatus = 127;
178 +                                               flushout(&errout);
179 +                                               goto out;
180 +                                       }
181 +                                       if (cmdentry.u.index != BLTINCMD)
182 +                                               break;
183 +                               }
184 +                       }
185 +                       if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == COMMANDCMD) {
186 +                               not_special = 1;
187                                 argv++;
188 -                               if (--argc == 0)
189 -                                       break;
190 -                               if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
191 -                                       outfmt(&errout, "%s: not found\n", *argv);
192 -                                       exitstatus = 127;
193 -                                       flushout(&errout);
194 -                                       return;
195 +                               if (--argc == 0) {
196 +                                       exitstatus = 0;
197 +                                       goto out;
198                                 }
199 -                               if (cmdentry.u.index != BLTINCMD)
200 -                                       break;
201 +                               if (*argv[0] == '-') {
202 +                                       if (!equal(argv[0], "-p")) {
203 +                                               argv--;
204 +                                               argc++;
205 +                                               break;
206 +                                       }
207 +                                       argv++;
208 +                                       if (--argc == 0) {
209 +                                               exitstatus = 0;
210 +                                               goto out;
211 +                                       }
212 +                                       if (!standard_path) {
213 +                                               standard_path = get_standard_path();
214 +                                       }
215 +                                       oldpath = path;
216 +                                       path = standard_path;
217 +                                       findflag |= DO_BRUTE;
218 +                               }
219 +                               findflag |= DO_NOFUN;
220 +                               continue;
221                         }
222 +                       break;
223                 }
224         }
225  
226 @@ -756,13 +825,12 @@
227  #ifdef DEBUG
228                 trputs("Shell function:  ");  trargs(argv);
229  #endif
230 +               exitstatus = oexitstatus;
231                 redirect(cmd->ncmd.redirect, REDIR_PUSH);
232                 saveparam = shellparam;
233                 shellparam.malloc = 0;
234 -               shellparam.reset = 1;
235                 shellparam.nparam = argc - 1;
236                 shellparam.p = argv + 1;
237 -               shellparam.optnext = NULL;
238                 INTOFF;
239                 savelocalvars = localvars;
240                 localvars = NULL;
241 @@ -772,6 +840,8 @@
242                                 freeparam((volatile struct shparam *)
243                                     &saveparam);
244                         } else {
245 +                               saveparam.optind = shellparam.optind;
246 +                               saveparam.optoff = shellparam.optoff;
247                                 freeparam(&shellparam);
248                                 shellparam = saveparam;
249                         }
250 @@ -790,6 +860,8 @@
251                 INTOFF;
252                 poplocalvars();
253                 localvars = savelocalvars;
254 +               saveparam.optind = shellparam.optind;
255 +               saveparam.optoff = shellparam.optoff;
256                 freeparam(&shellparam);
257                 shellparam = saveparam;
258                 handler = savehandler;
259 @@ -832,6 +908,8 @@
260                 out1 = &output;
261                 out2 = &errout;
262                 freestdout();
263 +               if (!not_special && is_special_builtin(commandname))
264 +                       listsetvar(cmdenviron);
265                 cmdenviron = NULL;
266                 if (e != EXSHELLPROC) {
267                         commandname = savecmdname;
268 @@ -867,7 +953,7 @@
269                 for (sp = varlist.list ; sp ; sp = sp->next)
270                         setvareq(sp->text, VEXPORT|VSTACK);
271                 envp = environment();
272 -               shellexec(argv, envp, pathval(), cmdentry.u.index);
273 +               shellexec(argv, envp, path, cmdentry.u.index);
274         }
275         goto out;
276  
277 @@ -1025,4 +1111,49 @@
278                 shellexec(argv + 1, environment(), pathval(), 0);
279         }
280         return 0;
281 +}
282 +
283 +STATIC int
284 +is_assignment_builtin (command)
285 +       const char *command;
286 +{
287 +       static const char *assignment_builtins[] = {
288 +               "alias", "declare", "export", "local", "readonly", "typeset",
289 +               (char *)NULL
290 +       };
291 +       int i;
292 +
293 +       for (i = 0; assignment_builtins[i]; i++)
294 +               if (strcmp(command, assignment_builtins[i]) == 0) return 1;
295 +       return 0;
296 +}
297 +
298 +int
299 +is_special_builtin(name)
300 +       const char *name;
301 +{
302 +       static const char *special_builtins[] = {
303 +               "break", ":", ".", "continue", "eval", "exec", "exit",
304 +               "export", "readonly", "return", "set", "shift", "times",
305 +               "trap", "unset", (char *)NULL
306 +       };
307 +       int i;
308 +
309 +       if (!name) return 0;
310 +       for (i = 0; special_builtins[i]; i++)
311 +               if (equal(name, special_builtins[i])) return 1;
312 +       return 0;
313 +}
314 +
315 +STATIC const char *
316 +get_standard_path()
317 +{
318 +       char *p;
319 +       size_t len;
320 +
321 +       len = confstr(_CS_PATH, NULL, 0);
322 +       p = stalloc(len + 2);
323 +       *p = '\0';
324 +       confstr(_CS_PATH, p, len);
325 +       return p;
326  }
327 diff -urN netbsd-sh/eval.h ash-0.3.7.orig/eval.h
328 --- netbsd-sh/eval.h    Fri Jan 28 13:03:00 2000
329 +++ ash-0.3.7.orig/eval.h       Mon Apr 23 22:16:46 2001
330 @@ -61,6 +61,7 @@
331  int falsecmd __P((int, char **));
332  int truecmd __P((int, char **));
333  int execcmd __P((int, char **));
334 +int is_special_builtin __P((const char *));
335  
336  /* in_function returns nonzero if we are currently evaluating a function */
337  #define in_function()  funcnest
338 diff -urN netbsd-sh/exec.c ash-0.3.7.orig/exec.c
339 --- netbsd-sh/exec.c    Fri Jan 12 17:50:35 2001
340 +++ ash-0.3.7.orig/exec.c       Mon Apr 23 22:16:46 2001
341 @@ -51,6 +51,7 @@
342  #include <fcntl.h>
343  #include <errno.h>
344  #include <stdlib.h>
345 +#include <sysexits.h>
346  
347  /*
348   * When commands are first encountered, they are entered in a hash table.
349 @@ -108,6 +109,9 @@
350  STATIC void clearcmdentry __P((int));
351  STATIC struct tblentry *cmdlookup __P((char *, int));
352  STATIC void delete_cmd_entry __P((void));
353 +STATIC int describe_command __P((char *, int));
354 +STATIC int path_change __P((const char *, int *));
355 +STATIC int is_regular_builtin __P((const char *));
356  
357  
358  
359 @@ -164,7 +172,7 @@
360         char **envp;
361         {
362         int e;
363 -#ifndef BSD
364 +#if !defined(BSD) && !defined(linux)
365         char *p;
366  #endif
367  
368 @@ -180,7 +188,7 @@
369                 initshellproc();
370                 setinputfile(cmd, 0);
371                 commandname = arg0 = savestr(argv[0]);
372 -#ifndef BSD
373 +#if !defined(BSD) && !defined(linux)
374                 pgetc(); pungetc();             /* fill up input buffer */
375                 p = parsenextc;
376                 if (parsenleft > 2 && p[0] == '#' && p[1] == '!') {
377 @@ -195,7 +203,7 @@
378  }
379  
380  
381 -#ifndef BSD
382 +#if !defined(BSD) && !defined(linux)
383  /*
384   * Execute an interpreter introduced by "#!", for systems where this
385   * feature has not been built into the kernel.  If the interpreter is
386 @@ -351,27 +359,29 @@
387         if (*argptr == NULL) {
388                 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
389                         for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
390 -                               printentry(cmdp, verbose);
391 +                               if (cmdp->cmdtype != CMDBUILTIN) {
392 +                                       printentry(cmdp, verbose);
393 +                               }
394                         }
395                 }
396                 return 0;
397         }
398 +       c = 0;
399         while ((name = *argptr) != NULL) {
400                 if ((cmdp = cmdlookup(name, 0)) != NULL
401                  && (cmdp->cmdtype == CMDNORMAL
402                      || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
403                         delete_cmd_entry();
404                 find_command(name, &entry, DO_ERR, pathval());
405 -               if (verbose) {
406 -                       if (entry.cmdtype != CMDUNKNOWN) {      /* if no error msg */
407 -                               cmdp = cmdlookup(name, 0);
408 -                               printentry(cmdp, verbose);
409 -                       }
410 +               if (entry.cmdtype == CMDUNKNOWN) c = 1;
411 +               else if (verbose) {
412 +                       cmdp = cmdlookup(name, 0);
413 +                       if (cmdp) printentry(cmdp, verbose);
414                         flushall();
415                 }
416                 argptr++;
417         }
418 -       return 0;
419 +       return c;
420  }
421  
422  
423 @@ -435,6 +445,10 @@
424         struct stat statb;
425         int e;
426         int i;
427 +       int bltin;
428 +       int firstchange;
429 +       int updatetbl;
430 +       int regular;
431  
432         /* If name contains a slash, don't use the hash table */
433         if (strchr(name, '/') != NULL) {
434 @@ -459,12 +473,54 @@
435                 return;
436         }
437  
438 +       updatetbl = 1;
439 +       if (act & DO_BRUTE) {
440 +               firstchange = path_change(path, &bltin);
441 +       } else {
442 +               bltin = builtinloc;
443 +               firstchange = 9999;
444 +       }
445 +
446         /* If name is in the table, and not invalidated by cd, we're done */
447 -       if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0)
448 -               goto success;
449 +       if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
450 +               if (cmdp->cmdtype == CMDFUNCTION) {
451 +                       if (act & DO_NOFUN) {
452 +                               updatetbl = 0;
453 +                       } else {
454 +                               goto success;
455 +                       }
456 +               } else if (act & DO_BRUTE) {
457 +                       if ((cmdp->cmdtype == CMDNORMAL &&
458 +                            cmdp->param.index >= firstchange) ||
459 +                           (cmdp->cmdtype == CMDBUILTIN &&
460 +                            ((builtinloc < 0 && bltin >= 0) ?
461 +                             bltin : builtinloc) >= firstchange)) {
462 +                               /* need to recompute the entry */
463 +                       } else {
464 +                               goto success;
465 +                       }
466 +               } else {
467 +                       goto success;
468 +               }
469 +       }
470 +
471 +       if ((regular = is_regular_builtin(name))) {
472 +               if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
473 +                       goto success;
474 +               }
475 +       } else if (act & DO_BRUTE) {
476 +               if (firstchange == 0) {
477 +                       updatetbl = 0;
478 +               }
479 +       }
480  
481         /* If %builtin not in path, check for builtin next */
482 -       if (builtinloc < 0 && (i = find_builtin(name)) >= 0) {
483 +       if ((bltin < 0 || regular) && (i = find_builtin(name)) >= 0) {
484 +               if (!updatetbl) {
485 +                       entry->cmdtype = CMDBUILTIN;
486 +                       entry->u.index = i;
487 +                       return;
488 +               }
489                 INTOFF;
490                 cmdp = cmdlookup(name, 1);
491                 cmdp->cmdtype = CMDBUILTIN;
492 @@ -475,7 +531,7 @@
493  
494         /* We have to search path. */
495         prev = -1;              /* where to start */
496 -       if (cmdp) {             /* doing a rehash */
497 +       if (cmdp && cmdp->rehash) {     /* doing a rehash */
498                 if (cmdp->cmdtype == CMDBUILTIN)
499                         prev = builtinloc;
500                 else
501 @@ -488,26 +544,38 @@
502         while ((fullname = padvance(&path, name)) != NULL) {
503                 stunalloc(fullname);
504                 idx++;
505 +               if (idx >= firstchange) {
506 +                       updatetbl = 0;
507 +               }
508                 if (pathopt) {
509                         if (prefix("builtin", pathopt)) {
510 -                               if ((i = find_builtin(name)) < 0)
511 -                                       goto loop;
512 -                               INTOFF;
513 -                               cmdp = cmdlookup(name, 1);
514 -                               cmdp->cmdtype = CMDBUILTIN;
515 -                               cmdp->param.index = i;
516 -                               INTON;
517 -                               goto success;
518 -                       } else if (prefix("func", pathopt)) {
519 +                               if ((i = find_builtin(name)) >= 0) {
520 +                                       if (!updatetbl) {
521 +                                               entry->cmdtype = CMDBUILTIN;
522 +                                               entry->u.index = i;
523 +                                               return;
524 +                                       }
525 +                                       INTOFF;
526 +                                       cmdp = cmdlookup(name, 1);
527 +                                       cmdp->cmdtype = CMDBUILTIN;
528 +                                       cmdp->param.index = i;
529 +                                       INTON;
530 +                                       goto success;
531 +                               } else {
532 +                                       continue;
533 +                               }
534 +                       } else if (!(act & DO_NOFUN) &&
535 +                                  prefix("func", pathopt)) {
536                                 /* handled below */
537                         } else {
538 -                               goto loop;      /* ignore unimplemented options */
539 +                               continue;       /* ignore unimplemented options */
540                         }
541                 }
542                 /* if rehash, don't redo absolute path names */
543 -               if (fullname[0] == '/' && idx <= prev) {
544 +               if (fullname[0] == '/' && idx <= prev &&
545 +                   idx < firstchange) {
546                         if (idx < prev)
547 -                               goto loop;
548 +                               continue;
549                         TRACE(("searchexec \"%s\": no change\n", name));
550                         goto success;
551                 }
552 @@ -522,7 +590,7 @@
553                 }
554                 e = EACCES;     /* if we fail, this will be the error */
555                 if (!S_ISREG(statb.st_mode))
556 -                       goto loop;
557 +                       continue;
558                 if (pathopt) {          /* this is a %func directory */
559                         stalloc(strlen(fullname) + 1);
560                         readcmdfile(fullname);
561 @@ -544,6 +612,13 @@
562                 }
563  #endif
564                 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
565 +               /* If we aren't called with DO_BRUTE and cmdp is set, it must
566 +                  be a function and we're being called with DO_NOFUN */
567 +               if (!updatetbl) {
568 +                       entry->cmdtype = CMDNORMAL;
569 +                       entry->u.index = idx;
570 +                       return;
571 +               }
572                 INTOFF;
573                 cmdp = cmdlookup(name, 1);
574                 cmdp->cmdtype = CMDNORMAL;
575 @@ -553,7 +628,7 @@
576         }
577  
578         /* We failed.  If there was an entry for this command, delete it */
579 -       if (cmdp)
580 +       if (cmdp && updatetbl)
581                 delete_cmd_entry();
582         if (act & DO_ERR)
583                 outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));
584 @@ -618,37 +693,12 @@
585  changepath(newval)
586         const char *newval;
587  {
588 -       const char *old, *new;
589 -       int idx;
590         int firstchange;
591         int bltin;
592  
593 -       old = pathval();
594 -       new = newval;
595 -       firstchange = 9999;     /* assume no change */
596 -       idx = 0;
597 -       bltin = -1;
598 -       for (;;) {
599 -               if (*old != *new) {
600 -                       firstchange = idx;
601 -                       if ((*old == '\0' && *new == ':')
602 -                        || (*old == ':' && *new == '\0'))
603 -                               firstchange++;
604 -                       old = new;      /* ignore subsequent differences */
605 -               }
606 -               if (*new == '\0')
607 -                       break;
608 -               if (*new == '%' && bltin < 0 && prefix("builtin", new + 1))
609 -                       bltin = idx;
610 -               if (*new == ':') {
611 -                       idx++;
612 -               }
613 -               new++, old++;
614 -       }
615 +       firstchange = path_change(newval, &bltin);
616         if (builtinloc < 0 && bltin >= 0)
617                 builtinloc = bltin;             /* zap builtins */
618 -       if (builtinloc >= 0 && bltin < 0)
619 -               firstchange = 0;
620         clearcmdentry(firstchange);
621         builtinloc = bltin;
622  }
623 @@ -838,11 +888,9 @@
624         {
625         struct cmdentry entry;
626  
627 -       INTOFF;
628         entry.cmdtype = CMDFUNCTION;
629         entry.u.func = copyfunc(func);
630         addcmdentry(name, &entry);
631 -       INTON;
632  }
633  
634  
635 @@ -944,4 +992,190 @@
636                 }
637         }
638         return err;
639 +}
640 +
641 +STATIC int
642 +describe_command(command, verbose)
643 +       char *command;
644 +       int verbose;
645 +{
646 +       struct cmdentry entry;
647 +       struct tblentry *cmdp;
648 +       char **pp;
649 +       struct alias *ap;
650 +       extern char *const parsekwd[];
651 +
652 +       for (pp = (char **)parsekwd; *pp; pp++)
653 +               if (**pp == *command && equal(*pp, command))
654 +                       break;
655 +
656 +       if (*pp) {
657 +               if (verbose) {
658 +                       out1fmt("%s is a reserved word\n", command);
659 +               } else {
660 +                       out1fmt("%s\n", command);
661 +               }
662 +               return 0;
663 +       }
664 +
665 +       /* Then look at the aliases */
666 +       if ((ap = lookupalias(command, 1)) != NULL) {
667 +               if (verbose) {
668 +                       out1fmt("%s is aliased to `%s'\n", command, ap->val);
669 +               } else {
670 +                       out1fmt("alias %s='%s'\n", command, ap->val);
671 +               }
672 +               return 0;
673 +       }
674 +
675 +       /* Then check if it is a tracked alias */
676 +       if ((cmdp = cmdlookup(command, 0)) != NULL) {
677 +               entry.cmdtype = cmdp->cmdtype;
678 +               entry.u = cmdp->param;
679 +       }
680 +       else {
681 +               /* Finally use brute force */
682 +               find_command(command, &entry, DO_ABS, pathval());
683 +       }
684 +
685 +       switch (entry.cmdtype) {
686 +       case CMDNORMAL: {
687 +               int j = entry.u.index;
688 +               const char *path = pathval();
689 +               char *name;
690 +               if (j == -1) 
691 +                       name = command;
692 +               else {
693 +                       do { 
694 +                               name = padvance(&path, command);
695 +                               stunalloc(name);
696 +                       } while (--j >= 0);
697 +               }
698 +               if (verbose) {
699 +                       out1fmt("%s is %s\n", command, name);
700 +               } else {
701 +                       out1fmt("%s\n", name);
702 +               }
703 +               break;
704 +       }
705 +       case CMDFUNCTION:
706 +               if (verbose) {
707 +                       out1fmt("%s is a function\n", command);
708 +               } else {
709 +                       out1fmt("%s\n", command);
710 +               }
711 +               break;
712 +       case CMDBUILTIN:
713 +               if (verbose) {
714 +                       if (is_special_builtin(command)) {
715 +                               out1fmt("%s is a special built-in utility\n", command);
716 +                       } else {
717 +                               out1fmt("%s is a built-in utility\n", command);
718 +                       }
719 +               } else {
720 +                       out1fmt("%s\n", command);
721 +               }
722 +               break;
723 +       default:
724 +               outfmt(out2, "%s not found\n", command);
725 +               return 127;
726 +       }
727 +
728 +       return 0;
729 +}
730 +
731 +int
732 +commandcmd(argc, argv)
733 +       int argc;
734 +       char **argv;
735 +{
736 +       int c;
737 +       int default_path = 0;
738 +       int verify_only = 0;
739 +       int verbose_verify_only = 0;
740 +
741 +       while ((c = nextopt("pvV")) != '\0')
742 +               switch (c) {
743 +               case 'p':
744 +                       default_path = 1;
745 +                       break;
746 +               case 'v':
747 +                       verify_only = 1;
748 +                       break;
749 +               case 'V':
750 +                       verbose_verify_only = 1;
751 +                       break;
752 +               default:
753 +                       outfmt(out2,
754 +"command: nextopt returned character code 0%o\n", c);
755 +                       return EX_SOFTWARE;
756 +               }
757 +
758 +       if (default_path + verify_only + verbose_verify_only > 1 ||
759 +           !*argptr) {
760 +                       outfmt(out2,
761 +"command [-p] command [arg ...]\n");
762 +                       outfmt(out2,
763 +"command {-v|-V} command\n");
764 +                       return EX_USAGE;
765 +       }
766 +
767 +       if (verify_only || verbose_verify_only) {
768 +               return describe_command(*argptr, verbose_verify_only);
769 +       }
770 +
771 +       return 0;
772 +}
773 +
774 +STATIC int
775 +path_change(newval, bltin)
776 +       const char *newval;
777 +       int *bltin;
778 +{
779 +       const char *old, *new;
780 +       int idx;
781 +       int firstchange;
782 +
783 +       old = pathval();
784 +       new = newval;
785 +       firstchange = 9999;     /* assume no change */
786 +       idx = 0;
787 +       *bltin = -1;
788 +       for (;;) {
789 +               if (*old != *new) {
790 +                       firstchange = idx;
791 +                       if ((*old == '\0' && *new == ':')
792 +                        || (*old == ':' && *new == '\0'))
793 +                               firstchange++;
794 +                       old = new;      /* ignore subsequent differences */
795 +               }
796 +               if (*new == '\0')
797 +                       break;
798 +               if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1))
799 +                       *bltin = idx;
800 +               if (*new == ':') {
801 +                       idx++;
802 +               }
803 +               new++, old++;
804 +       }
805 +       if (builtinloc >= 0 && *bltin < 0)
806 +               firstchange = 0;
807 +       return firstchange;
808 +}
809 +
810 +STATIC int
811 +is_regular_builtin(name)
812 +        const char *name;
813 +{
814 +        static const char *regular_builtins[] = {
815 +               "alias", "bg", "cd", "command", "false", "fc", "fg",
816 +               "getopts", "jobs", "kill", "newgrp", "read", "true",
817 +               "umask", "unalias", "wait", (char *)NULL
818 +        };
819 +        int i;
820 +
821 +        if (!name) return 0;
822 +        for (i = 0; regular_builtins[i]; i++)
823 +                if (equal(name, regular_builtins[i])) return 1;
824 +        return 0;
825  }
826 diff -urN netbsd-sh/exec.h ash-0.3.7.orig/exec.h
827 --- netbsd-sh/exec.h    Tue May 23 12:03:19 2000
828 +++ ash-0.3.7.orig/exec.h       Mon Apr 23 22:16:46 2001
829 @@ -56,6 +56,8 @@
830  
831  #define DO_ERR 1               /* find_command prints errors */
832  #define DO_ABS 2               /* find_command checks absolute paths */
833 +#define DO_NOFUN       4       /* find_command ignores functions */
834 +#define DO_BRUTE       8       /* find_command ignores hash table */
835  
836  extern const char *pathopt;    /* set by padvance */
837  extern int exerrno;            /* last exec error */
838 @@ -74,3 +76,4 @@
839  void defun __P((char *, union node *));
840  int unsetfunc __P((char *));
841  int typecmd __P((int, char **));
842 +int commandcmd __P((int, char **));
843
This page took 0.163628 seconds and 3 git commands to generate.