Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Can't trace script not in PATH



On Fri, 12 Mar 2010 16:07:35 +0100
"LORANG Geert" <geert.lorang@xxxxxxxxxxxxxxx> 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) <K> <S>)(
+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 <pws@xxxxxxx>            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



Messages sorted by: Reverse Date, Date, Thread, Author