From 53745d8df0a6e00d2ddf1c08f7ea71820d587673 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 16 Mar 2010 09:43:51 +0000 Subject: 27793 and follow ups: add PATH_SCRIPT option to find script using $PATH --- Src/init.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 21 deletions(-) (limited to 'Src/init.c') 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 (;;) { -- cgit 1.4.1