zsh-workers
 help / color / mirror / code / Atom feed
* Re: Can't trace script not in PATH
       [not found] <38D4FA2BB99A674BADDED237051D97A70EE02067@FFBRUE001.cfmu.corp.eurocontrol.int>
@ 2010-03-15 12:59 ` Peter Stephenson
  2010-03-15 14:03   ` Peter Stephenson
                     ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Peter Stephenson @ 2010-03-15 12:59 UTC (permalink / raw)
  To: LORANG Geert, Zsh Hackers' List

On Fri, 12 Mar 2010 16:07:35 +0100
"LORANG Geert" <geert.lorang@eurocontrol.int> 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@csr.com>            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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Can't trace script not in PATH
  2010-03-15 12:59 ` Can't trace script not in PATH Peter Stephenson
@ 2010-03-15 14:03   ` Peter Stephenson
  2010-03-15 15:30   ` Peter Stephenson
  2010-08-23 13:27   ` Mikael Magnusson
  2 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2010-03-15 14:03 UTC (permalink / raw)
  To: Zsh Hackers' List

On Mon, 15 Mar 2010 12:59:23 +0000
Peter Stephenson <pws@csr.com> wrote:
> +    /* sets INTERACTIVE, SHINSTDIN and SINGLECOMMAND */
> +    parseargs(argv, &runscript);
>  
>      SHTTY = -1;
>      init_io();
>      setupvals();
> +    setupshin(runscript);
> +
>      init_signals();
>      init_bltinmods();
>      init_builtins();

ackshly, the new code should be after run_init_scripts(), just off the
bottom of the hunk, to ensure PATH has been set up, so I will move it.
(Remember all I'm changing is how we find the file, I'm not changing
anything to do with where code is executed, although it will now execute
start-up files even if can't find the script which didn't happen before.)

-- 
Peter Stephenson <pws@csr.com>            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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Can't trace script not in PATH
  2010-03-15 12:59 ` Can't trace script not in PATH Peter Stephenson
  2010-03-15 14:03   ` Peter Stephenson
@ 2010-03-15 15:30   ` Peter Stephenson
  2010-08-23 13:27   ` Mikael Magnusson
  2 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2010-03-15 15:30 UTC (permalink / raw)
  To: Zsh Hackers' List

On Mon, 15 Mar 2010 12:59:23 +0000
Peter Stephenson <pws@csr.com> wrote:
>      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++;
>  	}

one more issue here... we should set argzero ($0) at this point if cmd is
set since we won't execute the code for *runscript non-NULL.  This affects

zsh -c 'echo $0' foo

where time-honoured (well, time-somethinged anyway) behaviour is that $0
returns "foo".  I'll add a test for this, too.

I don't think it's right to set scriptfilename in this case (i.e. -c,
obviously we set it if there's a real script), however.  It's used for
debugging and it's just confusing to have the debug output look like it's
running a script it isn't.

-- 
Peter Stephenson <pws@csr.com>            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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Can't trace script not in PATH
  2010-03-15 12:59 ` Can't trace script not in PATH Peter Stephenson
  2010-03-15 14:03   ` Peter Stephenson
  2010-03-15 15:30   ` Peter Stephenson
@ 2010-08-23 13:27   ` Mikael Magnusson
  2010-08-23 13:41     ` Peter Stephenson
  2 siblings, 1 reply; 5+ messages in thread
From: Mikael Magnusson @ 2010-08-23 13:27 UTC (permalink / raw)
  To: zsh workers

On 15 March 2010 14:59, Peter Stephenson <pws@csr.com> wrote:
> 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)).

% grep INVOCATION Doc/**/*.1
Doc/zsh.1:.SH "INVOCATION"
Doc/zshall.1:.SH "INVOCATION"
Doc/zshoptions.1:the section INVOCATION in \fIzshmisc\fP(1)\&.

so should it say zmanref(zsh) instead, or is invoke.yo included in the
wrong manpage?

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Can't trace script not in PATH
  2010-08-23 13:27   ` Mikael Magnusson
@ 2010-08-23 13:41     ` Peter Stephenson
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2010-08-23 13:41 UTC (permalink / raw)
  To: zsh workers

On Mon, 23 Aug 2010 15:27:21 +0200
Mikael Magnusson <mikachu@gmail.com> wrote:
> > then in the +command path.  See
> > +ifnzman(noderef(Invocation))\
> > +ifzman(the section INVOCATION in zmanref(zshmisc)).
>...
> so should it say zmanref(zsh) instead, or is invoke.yo included in the
> wrong manpage?

It should say zmanref(zsh).  Thanks, I've fixed it.

-- 
Peter Stephenson <pws@csr.com>            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


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-08-23 13:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <38D4FA2BB99A674BADDED237051D97A70EE02067@FFBRUE001.cfmu.corp.eurocontrol.int>
2010-03-15 12:59 ` Can't trace script not in PATH Peter Stephenson
2010-03-15 14:03   ` Peter Stephenson
2010-03-15 15:30   ` Peter Stephenson
2010-08-23 13:27   ` Mikael Magnusson
2010-08-23 13:41     ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).