From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20612 invoked by alias); 15 Mar 2010 13:05:07 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 27793 Received: (qmail 14020 invoked from network); 15 Mar 2010 13:05:04 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-3.0 required=5.0 tests=AWL,BAYES_00, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS autolearn=ham version=3.2.5 Received-SPF: none (ns1.primenet.com.au: domain at csr.com does not designate permitted sender hosts) Date: Mon, 15 Mar 2010 12:59:23 +0000 From: Peter Stephenson To: "LORANG Geert" , "Zsh Hackers' List" Subject: Re: Can't trace script not in PATH Message-ID: <20100315125923.63a6afa6@news01> In-Reply-To: <38D4FA2BB99A674BADDED237051D97A70EE02067@FFBRUE001.cfmu.corp.eurocontrol.int> References: <38D4FA2BB99A674BADDED237051D97A70EE02067@FFBRUE001.cfmu.corp.eurocontrol.int> Organization: CSR X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.8; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 15 Mar 2010 12:59:24.0404 (UTC) FILETIME=[56578340:01CAC43F] X-Scanned-By: MailControl A-09-22-10 (www.mailcontrol.com) on 10.71.1.140 On Fri, 12 Mar 2010 16:07:35 +0100 "LORANG Geert" wrote: > $ ksh -x testscript > testscript: can't open input file: testscript > > Ksh/zsh won't search PATH... > > So, is this a bug? No, in the sense that it's the intended behaviour that zsh has always had, but it's a long-standing incompatibility with Bourne-type shells that it would be good to fix (so I've moved this to zsh-workers). I've made this a new option, PATH_SCRIPT, which is on in the appropriate emulations. It's not entirely trivial since now we need the path to be set up before we open the script file. I hope this change does it without decapitating any of the statuary on the way down the corridor. It looks like the invocation section in the manual was missing any description of the shell opening a script file; it was implied elsewhere but never stated. Did I miss something somewhere else? Index: Doc/Zsh/invoke.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/invoke.yo,v retrieving revision 1.8 diff -p -u -r1.8 invoke.yo --- Doc/Zsh/invoke.yo 21 Oct 2005 09:51:55 -0000 1.8 +++ Doc/Zsh/invoke.yo 15 Mar 2010 12:58:01 -0000 @@ -1,7 +1,7 @@ texinode(Invocation)(Files)(Roadmap)(Top) chapter(Invocation) cindex(invocation) -sect(Invocation Options) +sect(Invocation) cindex(shell options) cindex(options, shell) cindex(shell flags) @@ -17,7 +17,8 @@ first one is assigned to tt($0), rather parameter. ) item(tt(-i))( -Force shell to be interactive. +Force shell to be interactive. It is still possible to specify a +script to execute. ) item(tt(-s))( Force shell to read commands from the standard input. @@ -27,6 +28,15 @@ execute. ) enditem() +If there are any remaining arguments after option processing, and neither +of the options tt(-c) or tt(-s) was supplied, the first argument is taken +as the file name of a script containing shell commands to be executed. If +the option tt(PATH_SCRIPT) is set, and the file name does not contain a +directory path (i.e. there is no `tt(/)' in the name), first the current +directory and then the command path given by the variable tt(PATH) are +searched for the script. If the option is not set or the file name +contains a `tt(/)' it is used directly. + After the first one or two arguments have been appropriated as described above, the remaining arguments are assigned to the positional parameters. Index: Doc/Zsh/options.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/options.yo,v retrieving revision 1.90 diff -p -u -r1.90 options.yo --- Doc/Zsh/options.yo 4 Feb 2010 17:40:07 -0000 1.90 +++ Doc/Zsh/options.yo 15 Mar 2010 12:58:01 -0000 @@ -1138,6 +1138,20 @@ executables specified in this form. Thi indicated by this option, and regardless of whether `tt(.)' or the current directory appear in the command search path. ) +pindex(PATH_SCRIPT) +pindex(NO_PATH_SCRIPT) +pindex(PATHSCRIPT) +pindex(NOPATHSCRIPT) +cindex(path search, for script argument to shell) +item(tt(PATH_SCRIPT) )( +If this option is not set, a script passed as the first non-option argument +to the shell must contain the name of the file to open. If this +option is set, and the script does not specify a directory path, +the script is looked for first in the current directory, then in the +command path. See +ifnzman(noderef(Invocation))\ +ifzman(the section INVOCATION in zmanref(zshmisc)). +) pindex(PRINT_EIGHT_BIT) pindex(NO_PRINT_EIGHT_BIT) pindex(PRINTEIGHTBIT) Index: Src/init.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/init.c,v retrieving revision 1.112 diff -p -u -r1.112 init.c --- Src/init.c 11 Mar 2010 22:40:58 -0000 1.112 +++ Src/init.c 15 Mar 2010 12:58:02 -0000 @@ -219,8 +219,8 @@ static char *cmd; static int restricted; /**/ -void -parseargs(char **argv) +static void +parseargs(char **argv, char **runscript) { int optionbreak = 0; char **x; @@ -336,14 +336,8 @@ parseargs(char **argv) if (*argv) { if (unset(SHINSTDIN)) { if (!cmd) - SHIN = movefd(open(unmeta(*argv), O_RDONLY | O_NOCTTY)); - if (SHIN == -1) { - zerr("can't open input file: %s", *argv); - exit(127); - } + *runscript = *argv; opts[INTERACTIVE] &= 1; - argzero = *argv; - scriptfilename = argzero; argv++; } while (*argv) @@ -737,7 +731,6 @@ setupvals(void) zero_mnumber.type = MN_INTEGER; zero_mnumber.u.l = 0; - lineno = 1; noeval = 0; curhist = 0; histsiz = DEFAULT_HISTSIZE; @@ -915,14 +908,6 @@ setupvals(void) hsubl = hsubr = NULL; lastpid = 0; lastpid_status = -1L; - bshin = SHIN ? fdopen(SHIN, "r") : stdin; - if (isset(SHINSTDIN) && !SHIN && unset(INTERACTIVE)) { -#ifdef _IONBF - setvbuf(stdin, NULL, _IONBF, 0); -#else - setlinebuf(stdin); -#endif - } get_usage(); @@ -935,6 +920,78 @@ setupvals(void) set_default_colour_sequences(); } +/* + * Setup shell input, opening any script file (runscript, may be NULL). + * This is deferred until we have a path to search, in case + * PATHSCRIPT is set for sh-compatible behaviour. + */ +static void +setupshin(char *runscript) +{ + if (runscript) { + char *funmeta, *sfname = NULL; + struct stat st; + + funmeta = unmeta(runscript); + /* + * Always search the current directory first. + */ + if (access(funmeta, F_OK) == 0 && + stat(funmeta, &st) >= 0 && + !S_ISDIR(st.st_mode)) + sfname = runscript; + else if (isset(PATHSCRIPT) && !strchr(runscript, '/')) { + /* + * With the PATHSCRIPT option, search the path if no + * path was given in the script name. + */ + char **pp, ppmaxlen = 0, *buf; + for (pp = path; *pp; pp++) + { + int len = strlen(*pp); + if (len > ppmaxlen) + ppmaxlen = len; + } + buf = zhalloc(ppmaxlen + strlen(runscript) + 2); + for (pp = path; *pp; pp++) { + sprintf(buf, "%s/%s", *pp, runscript); + /* careful, static buffer used in open() later */ + funmeta = unmeta(buf); + if (access(funmeta, F_OK) == 0 && + stat(funmeta, &st) >= 0 && + !S_ISDIR(st.st_mode)) { + sfname = buf; + break; + } + } + } + if (!sfname || + (SHIN = movefd(open(funmeta, O_RDONLY | O_NOCTTY))) + == -1) { + zerr("can't open input file: %s", runscript); + exit(127); + } + scriptfilename = sfname; + argzero = runscript; + } + /* + * We only initialise line numbering once there is a script to + * read commands from. + */ + lineno = 1; + /* + * Finish setting up SHIN and its relatives. + */ + bshin = SHIN ? fdopen(SHIN, "r") : stdin; + if (isset(SHINSTDIN) && !SHIN && unset(INTERACTIVE)) { +#ifdef _IONBF + setvbuf(stdin, NULL, _IONBF, 0); +#else + setlinebuf(stdin); +#endif + } +} + /* Initialize signal handling */ /**/ @@ -1389,7 +1446,7 @@ mod_export int use_exit_printed; mod_export int zsh_main(UNUSED(int argc), char **argv) { - char **t; + char **t, *runscript = NULL; int t0; #ifdef USE_LOCALE setlocale(LC_ALL, ""); @@ -1437,11 +1494,14 @@ zsh_main(UNUSED(int argc), char **argv) opts[LOGINSHELL] = (**argv == '-'); opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid()); opts[USEZLE] = 1; /* may be unset in init_io() */ - parseargs(argv); /* sets INTERACTIVE, SHINSTDIN and SINGLECOMMAND */ + /* sets INTERACTIVE, SHINSTDIN and SINGLECOMMAND */ + parseargs(argv, &runscript); SHTTY = -1; init_io(); setupvals(); + setupshin(runscript); + init_signals(); init_bltinmods(); init_builtins(); Index: Src/options.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/options.c,v retrieving revision 1.53 diff -p -u -r1.53 options.c --- Src/options.c 27 Jan 2010 19:25:34 -0000 1.53 +++ Src/options.c 15 Mar 2010 12:58:02 -0000 @@ -198,6 +198,7 @@ static struct optname optns[] = { {{NULL, "octalzeroes", OPT_EMULATE|OPT_SH}, OCTALZEROES}, {{NULL, "overstrike", 0}, OVERSTRIKE}, {{NULL, "pathdirs", OPT_EMULATE}, PATHDIRS}, +{{NULL, "pathscript", OPT_EMULATE|OPT_BOURNE}, PATHSCRIPT}, {{NULL, "posixaliases", OPT_EMULATE|OPT_BOURNE}, POSIXALIASES}, {{NULL, "posixbuiltins", OPT_EMULATE|OPT_BOURNE}, POSIXBUILTINS}, {{NULL, "posixcd", OPT_EMULATE|OPT_BOURNE}, POSIXCD}, Index: Src/zsh.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v retrieving revision 1.164 diff -p -u -r1.164 zsh.h --- Src/zsh.h 11 Mar 2010 22:41:05 -0000 1.164 +++ Src/zsh.h 15 Mar 2010 12:58:02 -0000 @@ -1977,6 +1977,7 @@ enum { OCTALZEROES, OVERSTRIKE, PATHDIRS, + PATHSCRIPT, POSIXALIASES, POSIXBUILTINS, POSIXCD, Index: Test/A01grammar.ztst =================================================================== RCS file: /cvsroot/zsh/zsh/Test/A01grammar.ztst,v retrieving revision 1.25 diff -p -u -r1.25 A01grammar.ztst --- Test/A01grammar.ztst 11 Jul 2009 16:43:01 -0000 1.25 +++ Test/A01grammar.ztst 15 Mar 2010 12:58:02 -0000 @@ -559,3 +559,16 @@ . ./dot_status 0:"." file sees status from previous command >1 + + mkdir test_path_script + print "#!/bin/sh\necho Found the script." >test_path_script/myscript + chmod u+x test_path_script/myscript + path=($PWD/test_path_script $path) + export PATH + $ZTST_testdir/../Src/zsh -f -o pathscript myscript +0:PATHSCRIPT option +>Found the script. + + $ZTST_testdir/../Src/zsh -f myscript +127q:PATHSCRIPT option not used. +?$ZTST_testdir/../Src/zsh: can't open input file: myscript -- Peter Stephenson Software Engineer Tel: +44 (0)1223 692070 Cambridge Silicon Radio Limited Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom