zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <pws@csr.com>
To: "LORANG Geert" <geert.lorang@eurocontrol.int>,
	"Zsh Hackers' List" <zsh-workers@zsh.org>
Subject: Re: Can't trace script not in PATH
Date: Mon, 15 Mar 2010 12:59:23 +0000	[thread overview]
Message-ID: <20100315125923.63a6afa6@news01> (raw)
In-Reply-To: <38D4FA2BB99A674BADDED237051D97A70EE02067@FFBRUE001.cfmu.corp.eurocontrol.int>

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


       reply	other threads:[~2010-03-15 13:05 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <38D4FA2BB99A674BADDED237051D97A70EE02067@FFBRUE001.cfmu.corp.eurocontrol.int>
2010-03-15 12:59 ` Peter Stephenson [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100315125923.63a6afa6@news01 \
    --to=pws@csr.com \
    --cc=geert.lorang@eurocontrol.int \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).