From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16526 invoked from network); 10 Sep 2003 21:16:24 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 10 Sep 2003 21:16:24 -0000 Received: (qmail 24487 invoked by alias); 10 Sep 2003 21:16:14 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 19059 Received: (qmail 24476 invoked from network); 10 Sep 2003 21:16:14 -0000 Received: from localhost (HELO sunsite.dk) (127.0.0.1) by localhost with SMTP; 10 Sep 2003 21:16:14 -0000 X-MessageWall-Score: 0 (sunsite.dk) Received: from [80.184.45.166] by sunsite.dk (MessageWall 1.0.8) with SMTP; 10 Sep 2003 21:16:12 -0000 Received: from opk by athlon with esmtp (masqmail 0.2.20) id 19xBUo-4Qy-00 for ; Wed, 10 Sep 2003 22:23:22 +0200 From: Oliver Kiddle To: Zsh workers Subject: PATCH: options to command builtin Date: Wed, 10 Sep 2003 22:23:22 +0200 Message-ID: <17047.1063225402@athlon> Sender: okiddle@yahoo.co.uk This long overdue patch adds support for the various flags to the command builtin required by posix. -v and -V are similar to what whence already does. -p uses a default path to search for commands instead of $path. Oliver diff -urw zsh/acconfig.h command-v/acconfig.h --- zsh/acconfig.h 2003-04-04 15:27:42.000000000 +0200 +++ command-v/acconfig.h 2003-09-10 20:48:49.000000000 +0200 @@ -52,6 +52,9 @@ * anything */ #undef GLOBAL_ZLOGOUT +/* The default path; used when running commands with command -p */ +#undef DEFAULT_PATH + /* Define to 1 if compiler could initialise a union */ #undef HAVE_UNION_INIT diff -urw zsh/Doc/Zsh/builtins.yo command-v/Doc/Zsh/builtins.yo --- zsh/Doc/Zsh/builtins.yo 2003-09-03 13:19:05.000000000 +0200 +++ command-v/Doc/Zsh/builtins.yo 2003-09-10 22:15:50.000000000 +0200 @@ -194,7 +194,18 @@ ) alias(chdir)(cd) module(clone)(zsh/clone) -prefix(command) +findex(command) +item(tt(command) [ tt(-pvV) ] var(simple command))( +The simple command argument is taken as an external command instead of +a function or builtin and is executed. If the tt(POSIX_BUILTINS) option +is set, builtins will also be executed but certain special properties +of them are suppressed. The tt(-p) flag causes a default path to be +searched instead of that in tt($path). With the tt(-v) flag, tt(command) +is similar to tt(whence) and with tt(-V), it is equivalent to tt(whence +-v). + +See also noderef(Precommand Modifiers). +) module(comparguments)(zsh/computil) module(compcall)(zsh/compctl) module(compctl)(zsh/compctl) diff -urw zsh/Src/builtin.c command-v/Src/builtin.c --- zsh/Src/builtin.c 2003-09-03 13:19:08.000000000 +0200 +++ command-v/Src/builtin.c 2003-09-10 20:48:31.000000000 +0200 @@ -2593,7 +2593,7 @@ return returnval; } -/* type, whence, which */ +/* type, whence, which, command */ /**/ int @@ -2603,6 +2603,7 @@ Patprog pprog; int returnval = 0; int printflags = 0; + int aliasflags; int csh, all, v, wd; int informed; char *cnam; @@ -2624,6 +2625,18 @@ if (OPT_ISSET(ops,'f')) printflags |= PRINT_WHENCE_FUNCDEF; + if (func == BIN_COMMAND) + if (OPT_ISSET(ops,'V')) { + printflags = aliasflags = PRINT_WHENCE_VERBOSE; + v = 1; + } else { + aliasflags = PRINT_LIST; + printflags = PRINT_WHENCE_SIMPLE; + v = 0; + } + else + aliasflags = printflags; + /* With -m option -- treat arguments as a glob patterns */ if (OPT_ISSET(ops,'m')) { for (; *argv; argv++) { @@ -2677,7 +2690,7 @@ /* Look for alias */ if ((hn = aliastab->getnode(aliastab, *argv))) { - aliastab->printnode(hn, printflags); + aliastab->printnode(hn, aliasflags); if (!all) continue; informed = 1; diff -urw zsh/Src/exec.c command-v/Src/exec.c --- zsh/Src/exec.c 2003-07-04 11:43:18.000000000 +0200 +++ command-v/Src/exec.c 2003-09-10 22:20:41.000000000 +0200 @@ -143,6 +143,10 @@ execarith, execautofn }; +/* structure for command builtin for when it is used with -v or -V */ +static struct builtin commandbn = + BUILTIN(0, 0, bin_whence, 0, -1, BIN_COMMAND, "vV", NULL); + /* parse string into a list */ /**/ @@ -243,7 +247,7 @@ * In zsh this traditionally executes the loop in the current shell, which * is nice to have if the loop does something to change the shell, like * setting parameters or calling builtins. - * Putting the loop in a sub-shell makes live easy, because the shell only + * Putting the loop in a sub-shell makes life easy, because the shell only * has to put it into the job-structure and then treats it as a normal * process. Suspending and interrupting is no problem then. * Some years ago, zsh either couldn't suspend such things at all, or @@ -257,7 +261,7 @@ * execlist->execpline->execcmd->execwhile->execlist->execpline * * (when waiting for the grep, ignoring execpline2 for now). At this time, - * zsh has build two job-table entries for it: one for the cat and one for + * zsh has built two job-table entries for it: one for the cat and one for * the grep. If the user hits ^Z at this point (and jobbing is used), the * shell is notified that the grep was suspended. The list_pipe flag is * used to tell the execpline where it was waiting that it was in a pipeline @@ -442,7 +446,7 @@ /**/ void -execute(Cmdnam not_used_yet, int dash) +execute(Cmdnam not_used_yet, int dash, int defpath) { Cmdnam cn; char buf[MAXCMDLEN], buf2[MAXCMDLEN]; @@ -451,7 +455,7 @@ int eno = 0, ee; arg0 = (char *) peekfirst(args); - if (isset(RESTRICTED) && strchr(arg0, '/')) { + if (isset(RESTRICTED) && (strchr(arg0, '/') || defpath)) { zerr("%s: restricted", arg0, 0); _exit(1); } @@ -474,8 +478,6 @@ zsfree(s); } - cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0); - /* If ARGV0 is in the commands environment, we use * * that as argv[0] for this external command */ if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) { @@ -507,7 +509,43 @@ break; } - if (cn) { + /* for command -p, search the default path */ + if (defpath) { + char *s, pbuf[PATH_MAX]; + char *dptr, *pe, *ps = DEFAULT_PATH; + + for(;ps;ps = pe ? pe+1 : NULL) { + pe = strchr(ps, ':'); + if (*ps == '/') { + s = pbuf; + if (pe) + struncpy(&s, ps, pe-ps); + else + strucpy(&s, ps); + *s++ = '/'; + if ((s - pbuf) + strlen(arg0) >= PATH_MAX) + continue; + strucpy(&s, arg0); + if (iscom(pbuf)) + break; + } + } + + if (!ps) { + zerr("command not found: %s", arg0, 0); + _exit(127); + } + + ee = zexecve(pbuf, argv); + + if ((dptr = strrchr(pbuf, '/'))) + *dptr = '\0'; + if (isgooderr(ee, *pbuf ? pbuf : "/")) + eno = ee; + + } else { + + if ((cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0))) { char nn[PATH_MAX], *dptr; if (cn->flags & HASHED) @@ -552,6 +590,8 @@ if (isgooderr(ee, *pp)) eno = ee; } + } + if (eno) zerr("%e: %s", arg0, eno); else @@ -1692,7 +1732,7 @@ int save[10]; int fil, dfil, is_cursh, type, do_exec = 0, i, htok = 0; int nullexec = 0, assign = 0, forked = 0; - int is_shfunc = 0, is_builtin = 0, is_exec = 0; + int is_shfunc = 0, is_builtin = 0, is_exec = 0, use_defpath = 0; /* Various flags to the command. */ int cflags = 0, checked = 0, oautocont = opts[AUTOCONTINUE]; LinkList redir; @@ -1782,9 +1822,30 @@ } cflags &= ~BINF_BUILTIN & ~BINF_COMMAND; cflags |= hn->flags; + checked = 0; + if (cflags & BINF_COMMAND && nextnode(firstnode(args))) { + // check for options to command builtin + char *next = (char *) getdata(nextnode(firstnode(args))); + char *cmdopt; + if (next && *next == '-' && strlen(next) == 2 && + (cmdopt = strchr("pvV", next[1]))) + { + if (*cmdopt == 'p') { + uremnode(args, firstnode(args)); + use_defpath = 1; + if (nextnode(firstnode(args))) + next = (char *) getdata(nextnode(firstnode(args))); + } else { + hn = (HashNode)&commandbn; + is_builtin = 1; + break; + } + } + if (!strcmp(next, "--")) + uremnode(args, firstnode(args)); + } uremnode(args, firstnode(args)); hn = NULL; - checked = 0; if ((cflags & BINF_COMMAND) && unset(POSIXBUILTINS)) break; } @@ -2401,7 +2462,7 @@ zsfree(STTYval); STTYval = 0; } - execute((Cmdnam) hn, cflags & BINF_DASH); + execute((Cmdnam) hn, cflags & BINF_DASH, use_defpath); } else { /* ( ... ) */ DPUTS(varspc, "BUG: assignment before complex command"); diff -urw zsh/Src/hashtable.h command-v/Src/hashtable.h --- zsh/Src/hashtable.h 2002-08-27 23:10:34.000000000 +0200 +++ command-v/Src/hashtable.h 2003-09-10 20:48:31.000000000 +0200 @@ -58,6 +58,7 @@ #define BIN_DISABLE 24 #define BIN_ENABLE 25 #define BIN_PRINTF 26 +#define BIN_COMMAND 27 /* These currently depend on being 0 and 1. */ #define BIN_SETOPT 0 diff -urw zsh/zshconfig.ac command-v/zshconfig.ac --- zsh/zshconfig.ac 2003-08-31 11:41:10.000000000 +0200 +++ command-v/zshconfig.ac 2003-09-10 20:48:49.000000000 +0200 @@ -1323,6 +1323,20 @@ fi +dnl -------------------------------------------- +dnl CHECK FOR DEFAULT PATH (used for command -p) +dnl -------------------------------------------- +AC_CACHE_VAL(zsh_cv_cs_path, +[if getconf _CS_PATH >/dev/null 2>&1; then + zsh_cv_cs_path=`getconf _CS_PATH` +elif getconf CS_PATH >/dev/null 2>&1; then + zsh_cv_cs_path=`getconf CS_PATH` +else + zsh_cv_cs_path="/bin:/usr/bin" +fi]) +AC_DEFINE_UNQUOTED(DEFAULT_PATH, "$zsh_cv_cs_path") + + dnl ---------------------------- dnl CHECK FOR /dev/fd FILESYSTEM dnl ----------------------------