| Summary: | /bin/sh: shell command "command -v cmd" doesn't work | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Bram <Bram> |
| Component: | bin | Assignee: | Stefan Farfeleder <stefanf> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
|
Description
Bram
2005-02-08 11:10:21 UTC
Here is some kind of patch:
--- eval.c.orig Wed Apr 7 00:06:51 2004
+++ eval.c Sat Feb 12 01:20:11 2005
@@ -970,8 +970,10 @@
static char stdpath[] = _PATH_STDPATH;
struct jmploc loc, *old;
struct strlist *sp;
+ struct cmdentry cent;
char *path;
int ch;
+ int vcmdflag = 0;
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
@@ -979,11 +981,14 @@
optind = optreset = 1;
opterr = 0;
- while ((ch = getopt(argc, argv, "p")) != -1) {
+ while ((ch = getopt(argc, argv, "pv")) != -1) {
switch (ch) {
case 'p':
path = stdpath;
break;
+ case 'v':
+ vcmdflag = 1;
+ break;
case '?':
default:
error("unknown option: -%c", optopt);
@@ -993,14 +998,32 @@
argv += optind;
if (argc != 0) {
- old = handler;
- handler = &loc;
- if (setjmp(handler->loc) == 0)
- shellexec(argv, environment(), path, 0);
- handler = old;
- if (exception == EXEXEC)
- exit(exerrno);
- exraise(exception);
+ if(!vcmdflag){
+ old = handler;
+ handler = &loc;
+ if (setjmp(handler->loc) == 0)
+ shellexec(argv, environment(), path, 0);
+ handler = old;
+ if (exception == EXEXEC)
+ exit(exerrno);
+ exraise(exception);
+ }
+ else{
+ find_command(argv[0], ¢, 0, path);
+
+ switch(cent.cmdtype) {
+ case CMDNORMAL:
+ out1fmt("%s\n", padvance(&path,
argv[0]));
+ break;
+ case CMDBUILTIN:
+ out1fmt("%s\n", argv[0]);
+ break;
+ default:
+ out1str("");
+ break;
+ }
+ flushall();
+ }
}
/*
Responsible Changed From-To: freebsd-bugs->stefanf I'll handle this. Stefan, Are you still working on this? I have a patch which implements command -v and command -V in terms of the existing "type" builtin command. -- Craig Rodrigues rodrigc@crodrigues.org Index: eval.c =================================================================== RCS file: /home/ncvs/src/bin/sh/eval.c,v retrieving revision 1.46 diff -u -u -r1.46 eval.c --- eval.c 10 Sep 2005 08:25:28 -0000 1.46 +++ eval.c 28 Oct 2005 02:47:08 -0000 @@ -983,12 +983,23 @@ optind = optreset = 1; opterr = 0; - while ((ch = getopt(argc, argv, "p")) != -1) { + while ((ch = getopt(argc, argv, "pv:V:")) != -1) { switch (ch) { case 'p': path = stdpath; break; + case 'v': { + char *new_argv[] = {"type", optarg, 0 }; + return(typecmd_impl(2, new_argv, 0)); + } + break; + case 'V': { + char *new_argv[] = {"type", optarg, 0 }; + return(typecmd_impl(2, new_argv, 1)); + } + break; case '?': + error("missing argument: -%c", optopt); default: error("unknown option: -%c", optopt); } Index: exec.c =================================================================== RCS file: /home/ncvs/src/bin/sh/exec.c,v retrieving revision 1.26 diff -u -u -r1.26 exec.c --- exec.c 13 Aug 2005 08:12:18 -0000 1.26 +++ exec.c 28 Oct 2005 02:47:08 -0000 @@ -705,11 +705,11 @@ } /* - * Locate and print what a word is... - */ - + * Shared code for the following builtin commands: + * type, command -v, command -V + */ int -typecmd(int argc, char **argv) +typecmd_impl(int argc, char **argv, int typecmd) { struct cmdentry entry; struct tblentry *cmdp; @@ -720,20 +720,30 @@ extern char *const parsekwd[]; for (i = 1; i < argc; i++) { - out1str(argv[i]); + if (typecmd) + out1str(argv[i]); + /* First look at the keywords */ for (pp = (char **)parsekwd; *pp; pp++) if (**pp == *argv[i] && equal(*pp, argv[i])) break; if (*pp) { - out1str(" is a shell keyword\n"); + if (typecmd) + out1str(" is a shell keyword\n"); + else + out1fmt("%s\n", argv[i]); + continue; } /* Then look at the aliases */ if ((ap = lookupalias(argv[i], 1)) != NULL) { - out1fmt(" is an alias for %s\n", ap->val); + if (typecmd) + out1fmt(" is an alias for %s\n", ap->val); + else + out1fmt("alias %s='%s'\n", argv[i], ap->val); + continue; } @@ -756,29 +766,59 @@ name = padvance(&path, argv[i]); stunalloc(name); } while (--j >= 0); - out1fmt(" is%s %s\n", - cmdp ? " a tracked alias for" : "", name); + + if (typecmd) { + out1fmt(" is%s %s\n", + cmdp ? " a tracked alias for" : "", name); + } else { + if (cmdp) + out1fmt("alias %s='%s'\n", argv[i], name); + else + out1fmt("%s\n", name); + } } else { - if (access(argv[i], X_OK) == 0) - out1fmt(" is %s\n", argv[i]); + if (access(argv[i], X_OK) == 0) { + if (typecmd) + out1fmt(" is %s\n", argv[i]); + else + out1fmt("%s\n", argv[i]); + } else out1fmt(": %s\n", strerror(errno)); } break; } case CMDFUNCTION: - out1str(" is a shell function\n"); + if (typecmd) + out1str(" is a shell function\n"); + else + out1fmt("%s\n", argv[i]); break; case CMDBUILTIN: - out1str(" is a shell builtin\n"); + if (typecmd) + out1str(" is a shell builtin\n"); + else + out1fmt("%s\n", argv[i]); break; default: - out1str(": not found\n"); + if (typecmd) + out1str(": not found\n"); + else + out1fmt("%s: not found\n", argv[i]); error |= 127; break; } } return error; } + +/* + * Locate and print what a word is... + */ +int +typecmd(int argc, char **argv) +{ + return typecmd_impl(argc, argv, 1); +} Index: exec.h =================================================================== RCS file: /home/ncvs/src/bin/sh/exec.h,v retrieving revision 1.12 diff -u -u -r1.12 exec.h --- exec.h 6 Apr 2004 20:06:51 -0000 1.12 +++ exec.h 28 Oct 2005 02:47:08 -0000 @@ -63,5 +63,6 @@ void addcmdentry(char *, struct cmdentry *); void defun(char *, union node *); int unsetfunc(char *); +int typecmd_impl(int, char **, int); int typecmd(int, char **); void clearcmdentry(int); State Changed From-To: open->patched A modified version of Craig's patch was committed to current. Thanks! State Changed
From-To: patched->closed
Also fixed in RELENG_{5,6}.
|