summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--Doc/Zsh/invoke.yo14
-rw-r--r--Doc/Zsh/options.yo14
-rw-r--r--Src/init.c104
-rw-r--r--Src/options.c1
-rw-r--r--Src/zsh.h1
-rw-r--r--Test/A01grammar.ztst18
7 files changed, 136 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 9fbed5276..f8ecd456d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-03-16 Peter Stephenson <pws@csr.com>
+
+ * 27793 plus 27794, 27795: Doc/Zsh/invoke.yo, Doc/Zsh/options.yo,
+ Src/init.c, Src/options.c, Src/zsh.h, Test/A01grammar.ztst:
+ add PATH_SCRIPT option to find script using path.
+
2010-03-15 Peter Stephenson <p.w.stephenson@ntlworld.com>
* Mikael: 27797: Completion/Base/Completer/_expand_alias:
@@ -12903,5 +12909,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4931 $
+* $Revision: 1.4932 $
*****************************************************
diff --git a/Doc/Zsh/invoke.yo b/Doc/Zsh/invoke.yo
index 01e9b00e6..e03c1e25b 100644
--- a/Doc/Zsh/invoke.yo
+++ b/Doc/Zsh/invoke.yo
@@ -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 than being used as a positional
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.
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index e0934ff3d..003071aab 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1138,6 +1138,20 @@ executables specified in this form. This takes place before any search
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)
diff --git a/Src/init.c b/Src/init.c
index c65c4aaad..56c8c1822 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -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;
@@ -335,15 +335,11 @@ 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);
- }
+ if (cmd)
+ argzero = *argv;
+ else
+ *runscript = *argv;
opts[INTERACTIVE] &= 1;
- argzero = *argv;
- scriptfilename = argzero;
argv++;
}
while (*argv)
@@ -737,7 +733,6 @@ setupvals(void)
zero_mnumber.type = MN_INTEGER;
zero_mnumber.u.l = 0;
- lineno = 1;
noeval = 0;
curhist = 0;
histsiz = DEFAULT_HISTSIZE;
@@ -915,14 +910,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 +922,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 +1448,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,15 +1496,18 @@ 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();
+
init_signals();
init_bltinmods();
init_builtins();
run_init_scripts();
+ setupshin(runscript);
init_misc();
for (;;) {
diff --git a/Src/options.c b/Src/options.c
index 705546699..dedbf0c73 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -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},
diff --git a/Src/zsh.h b/Src/zsh.h
index df7e251b9..1b1175cb2 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1977,6 +1977,7 @@ enum {
OCTALZEROES,
OVERSTRIKE,
PATHDIRS,
+ PATHSCRIPT,
POSIXALIASES,
POSIXBUILTINS,
POSIXCD,
diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst
index 3b3f2f915..94836b4e2 100644
--- a/Test/A01grammar.ztst
+++ b/Test/A01grammar.ztst
@@ -559,3 +559,21 @@
. ./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
+
+ $ZTST_testdir/../Src/zsh -c 'echo $0; echo $1' myargzero myargone
+0:$0 is traditionally if bizarrely set to the first argument with -c
+>myargzero
+>myargone