* Running "unset path" breaks PATH despite emulation being enabled @ 2017-09-08 8:29 Eric Pruitt 2017-09-08 11:30 ` Mikael Magnusson 0 siblings, 1 reply; 5+ messages in thread From: Eric Pruitt @ 2017-09-08 8:29 UTC (permalink / raw) To: zsh-workers According and <http://www.zsh.org/mla/users/2015/msg00180.html> and the manual, Z shell should become roughly POSIX compatible when using "emulate sh". When using emulation, running 'path=""' does not break PATH command execution, but running 'unset path' still does which seems like a bug to me: $ zsh -c 'emulate -L sh; path=""; ls /dev/null' /dev/null $ zsh -c 'emulate -L sh; unset path; ls /dev/null' zsh:1: command not found: ls Eric ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Running "unset path" breaks PATH despite emulation being enabled 2017-09-08 8:29 Running "unset path" breaks PATH despite emulation being enabled Eric Pruitt @ 2017-09-08 11:30 ` Mikael Magnusson 2017-09-08 16:17 ` Peter Stephenson 2017-09-09 4:24 ` Eric Pruitt 0 siblings, 2 replies; 5+ messages in thread From: Mikael Magnusson @ 2017-09-08 11:30 UTC (permalink / raw) To: Eric Pruitt; +Cc: zsh workers On Fri, Sep 8, 2017 at 10:29 AM, Eric Pruitt <eric.pruitt@gmail.com> wrote: > According and <http://www.zsh.org/mla/users/2015/msg00180.html> and the > manual, Z shell should become roughly POSIX compatible when using > "emulate sh". When using emulation, running 'path=""' does not break > PATH command execution, but running 'unset path' still does which seems > like a bug to me: > > $ zsh -c 'emulate -L sh; path=""; ls /dev/null' > /dev/null > $ zsh -c 'emulate -L sh; unset path; ls /dev/null' > zsh:1: command not found: ls This works fine if you start zsh as sh though, ie either make a symlink ln -s =zsh sh; ./sh or do ARGV0=sh zsh It can't really work in the 'emulate sh' case since the parameter $path is then already created and it would be quite controversial for emulate to remove parameters from the shell environment. -- Mikael Magnusson ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Running "unset path" breaks PATH despite emulation being enabled 2017-09-08 11:30 ` Mikael Magnusson @ 2017-09-08 16:17 ` Peter Stephenson 2017-09-11 8:58 ` Peter Stephenson 2017-09-09 4:24 ` Eric Pruitt 1 sibling, 1 reply; 5+ messages in thread From: Peter Stephenson @ 2017-09-08 16:17 UTC (permalink / raw) To: Zsh Hackers' List On Fri, 8 Sep 2017 13:30:05 +0200 Mikael Magnusson <mikachu@gmail.com> wrote: > > $ zsh -c 'emulate -L sh; path=""; ls /dev/null' > > /dev/null > > $ zsh -c 'emulate -L sh; unset path; ls /dev/null' > > zsh:1: command not found: ls > > This works fine if you start zsh as sh though, ie either make a > symlink ln -s =zsh sh; ./sh or do ARGV0=sh zsh > It can't really work in the 'emulate sh' case since the parameter > $path is then already created and it would be quite controversial for > emulate to remove parameters from the shell environment. All this is entirely correct. I wonder if it would be helpful for us to make it easier to set an emulation at invocation, i.e. "zsh --emulate sh ..."? pws diff --git a/Doc/Zsh/invoke.yo b/Doc/Zsh/invoke.yo index e03c1e2..da09c0f 100644 --- a/Doc/Zsh/invoke.yo +++ b/Doc/Zsh/invoke.yo @@ -46,6 +46,16 @@ ifzman(zmanref(zshoptions))\ ifnzman(noderef(Options))\ . +The long option `tt(--emulate)' followed (in a separate word) by an +emulation mode may be passed to the shell. +The emulation modes are those described for the tt(emulate) builtin, +see +ifzman(zmanref(zshbuiltins))\ +ifnzman(noderef(Shell Builtin Commands)). +The `tt(--emulate)' option must precede any other options (which might +otherwise be overridden), but following options are honoured, so +may be used to modify the requested emulation mode. + Options may be specified by name using the tt(-o) option. tt(-o) acts like a single-letter option, but takes a following string as the option name. For example, diff --git a/Src/builtin.c b/Src/builtin.c index 2e72ba2..0c2a62a 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5905,7 +5905,7 @@ bin_emulate(char *nam, char **argv, Options ops, UNUSED(int func)) savehackchar = keyboardhackchar; emulate(shname, opt_R, &new_emulation, new_opts); optlist = newlinklist(); - if (parseopts(nam, &argv, new_opts, &cmd, optlist)) { + if (parseopts(nam, &argv, new_opts, &cmd, optlist, 0)) { ret = 1; goto restore; } diff --git a/Src/init.c b/Src/init.c index 87dd2e2..cee12ac 100644 --- a/Src/init.c +++ b/Src/init.c @@ -244,10 +244,13 @@ static int restricted; /**/ static void -parseargs(char **argv, char **runscript, char **cmdptr) +parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr) { char **x; LinkList paramlist; + int flags = PARSEARGS_TOPLEVEL; + if (**argv == '-') + flags |= PARSEARGS_LOGIN; argzero = posixzero = *argv++; SHIN = 0; @@ -270,7 +273,7 @@ parseargs(char **argv, char **runscript, char **cmdptr) opts[SHINSTDIN] = 0; opts[SINGLECOMMAND] = 0; - if (parseopts(NULL, &argv, opts, cmdptr, NULL)) + if (parseopts(zsh_name, &argv, opts, cmdptr, NULL, flags)) exit(1); /* @@ -334,9 +337,27 @@ parseopts_insert(LinkList optlist, char *base, int optno) } /* + * This sets the global emulation plus the options we traditionally + * set immediately after that. This is jsut for historical consistency + * --- I don't think those options actually need to be set here. + */ +static void parseopts_setemulate(char *nam, int flags) +{ + emulate(nam, 1, &emulation, opts); /* initialises most options */ + opts[LOGINSHELL] = ((flags & PARSEARGS_LOGIN) != 0); + opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid()); +} + +/* * Parse shell options. - * If nam is not NULL, this is called from a command; don't - * exit on failure. + * + * If (flags & PARSEARGS_TOPLEVEL): + * - we are doing shell initilisation + * - nam is the name under which the shell was started + * - set up emulation and standard options based on that. + * Otherwise: + * - nam is a command name + * - don't exit on failure. * * If optlist is not NULL, it used to form a list of pointers * into new_opts indicating which options have been changed. @@ -345,23 +366,26 @@ parseopts_insert(LinkList optlist, char *base, int optno) /**/ mod_export int parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, - LinkList optlist) + LinkList optlist, int flags) { int optionbreak = 0; int action, optno; char **argv = *argvp; + int toplevel = ((flags & PARSEARGS_TOPLEVEL) != 0u); + int emulate_required = toplevel; + char *top_emulation = nam; *cmdp = 0; #define WARN_OPTION(F, S) \ do { \ - if (nam) \ + if (!toplevel) \ zwarnnam(nam, F, S); \ else \ zerr(F, S); \ } while (0) #define LAST_OPTION(N) \ do { \ - if (nam) { \ + if (!toplevel) { \ if (*argv) \ argv++; \ goto doneargv; \ @@ -381,7 +405,7 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, argv++; goto doneoptions; } - if (nam || *argv != args+1 || **argv != '-') + if (!toplevel || *argv != args+1 || **argv != '-') goto badoptionstring; /* GNU-style long options */ ++*argv; @@ -394,6 +418,19 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, printhelp(); LAST_OPTION(0); } + if (!strcmp(*argv, "emulate")) { + ++argv; + if (!*argv) { + zerr("--emulate: argument required"); + exit(1); + } + if (!emulate_required) { + zerr("--emulate: must precede other options"); + exit(1); + } + top_emulation = *argv; + break; + } /* `-' characters are allowed in long options */ for(args = *argv; *args; args++) if(*args == '-') @@ -402,9 +439,17 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, } if (unset(SHOPTIONLETTERS) && **argv == 'b') { + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } /* -b ends options at the end of this argument */ optionbreak = 1; } else if (**argv == 'c') { + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } /* -c command */ *cmdp = *argv; new_opts[INTERACTIVE] &= 1; @@ -417,15 +462,20 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, return 1; } longoptions: + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } if (!(optno = optlookup(*argv))) { WARN_OPTION("no such option: %s", *argv); return 1; - } else if (optno == RESTRICTED && !nam) { + } else if (optno == RESTRICTED && toplevel) { restricted = action; - } else if ((optno == EMACSMODE || optno == VIMODE) && nam) { + } else if ((optno == EMACSMODE || optno == VIMODE) && !toplevel) { WARN_OPTION("can't change option: %s", *argv); } else { - if (dosetopt(optno, action, !nam, new_opts) && nam) { + if (dosetopt(optno, action, toplevel, new_opts) && + !toplevel) { WARN_OPTION("can't change option: %s", *argv); } else if (optlist) { parseopts_insert(optlist, new_opts, optno); @@ -442,15 +492,21 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, } break; } else { + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } if (!(optno = optlookupc(**argv))) { WARN_OPTION("bad option: -%c", **argv); return 1; - } else if (optno == RESTRICTED && !nam) { + } else if (optno == RESTRICTED && toplevel) { restricted = action; - } else if ((optno == EMACSMODE || optno == VIMODE) && nam) { + } else if ((optno == EMACSMODE || optno == VIMODE) && + !toplevel) { WARN_OPTION("can't change option: %s", *argv); } else { - if (dosetopt(optno, action, !nam, new_opts) && nam) { + if (dosetopt(optno, action, toplevel, new_opts) && + !toplevel) { WARN_OPTION("can't change option: -%c", **argv); } else if (optlist) { parseopts_insert(optlist, new_opts, optno); @@ -470,6 +526,10 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, } doneargv: *argvp = argv; + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } return 0; } @@ -1660,11 +1720,9 @@ zsh_main(UNUSED(int argc), char **argv) fdtable[0] = fdtable[1] = fdtable[2] = FDT_EXTERNAL; createoptiontable(); - emulate(zsh_name, 1, &emulation, opts); /* initialises most options */ - opts[LOGINSHELL] = (**argv == '-'); - opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid()); - /* sets ZLE, INTERACTIVE, SHINSTDIN and SINGLECOMMAND */ - parseargs(argv, &runscript, &cmd); + /* sets emulation, LOGINSHELL, PRIVILEGED, ZLE, INTERACTIVE, + * SHINSTDIN and SINGLECOMMAND */ + parseargs(zsh_name, argv, &runscript, &cmd); SHTTY = -1; init_io(cmd); diff --git a/Src/zsh.h b/Src/zsh.h index abe9a9c..1e982a6 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1361,6 +1361,14 @@ struct options { int argscount, argsalloc; }; +/* Flags to parseargs() */ + +enum { + PARSEARGS_TOPLEVEL = 0x1, /* Call to initialise shell */ + PARSEARGS_LOGIN = 0x2 /* Shell is login shell */ +}; + + /* * Handler arguments are: builtin name, null-terminated argument * list excluding command name, option structure, the funcid element from the diff --git a/Test/B07emulate.ztst b/Test/B07emulate.ztst index 2de097e..7b1592f 100644 --- a/Test/B07emulate.ztst +++ b/Test/B07emulate.ztst @@ -251,3 +251,28 @@ emulate sh -c '[[ a == a ]]' 0:regression test for POSIX_ALIASES reserved words F:Some reserved tokens are handled in alias expansion + + for mode in ksh bash zsh; do + $ZTST_testdir/../Src/zsh --emulate $mode -f -c 'emulate' + done +0:--emulate option +>ksh +>sh +>zsh + + $ZTST_testdir/../Src/zsh -f --emulate sh +1:--emulate must be first +*?*: --emulate: must precede other options + + $ZTST_testdir/../Src/zsh --emulate +1:--emulate needs an argument +*?*: --emulate: argument required + + for opt in shwordsplit noshwordsplit; do + $ZTST_testdir/../Src/zsh --emulate sh -f -o $opt -c ' + [[ -o shwordsplit ]] && echo yes || echo no + ' + done +0:--emulate followed by other options +>yes +>no ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Running "unset path" breaks PATH despite emulation being enabled 2017-09-08 16:17 ` Peter Stephenson @ 2017-09-11 8:58 ` Peter Stephenson 0 siblings, 0 replies; 5+ messages in thread From: Peter Stephenson @ 2017-09-11 8:58 UTC (permalink / raw) To: Zsh Hackers' List On Fri, 8 Sep 2017 17:17:03 +0100 Peter Stephenson <p.stephenson@samsung.com> wrote: > All this is entirely correct. I wonder if it would be helpful for us to > make it easier to set an emulation at invocation, i.e. "zsh --emulate sh > ..."? I've slightly reordered to try to ensure the maximum compatibility with the previous code, and also added an extra sentence about the usefulness of --emulate compared with the emulate builtin. I'll commit this. pws diff --git a/Doc/Zsh/invoke.yo b/Doc/Zsh/invoke.yo index e03c1e2..a184bc8 100644 --- a/Doc/Zsh/invoke.yo +++ b/Doc/Zsh/invoke.yo @@ -46,6 +46,20 @@ ifzman(zmanref(zshoptions))\ ifnzman(noderef(Options))\ . +The long option `tt(--emulate)' followed (in a separate word) by an +emulation mode may be passed to the shell. +The emulation modes are those described for the tt(emulate) builtin, +see +ifzman(zmanref(zshbuiltins))\ +ifnzman(noderef(Shell Builtin Commands)). +The `tt(--emulate)' option must precede any other options (which might +otherwise be overridden), but following options are honoured, so +may be used to modify the requested emulation mode. Note that certain +extra steps are taken to ensure a smooth emulation when this option +is used compared with the tt(emulate) command within the shell: for +example, variables that conflict with POSIX usage such as tt(path) are +not defined within the shell. + Options may be specified by name using the tt(-o) option. tt(-o) acts like a single-letter option, but takes a following string as the option name. For example, diff --git a/Src/builtin.c b/Src/builtin.c index 2e72ba2..0c2a62a 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5905,7 +5905,7 @@ bin_emulate(char *nam, char **argv, Options ops, UNUSED(int func)) savehackchar = keyboardhackchar; emulate(shname, opt_R, &new_emulation, new_opts); optlist = newlinklist(); - if (parseopts(nam, &argv, new_opts, &cmd, optlist)) { + if (parseopts(nam, &argv, new_opts, &cmd, optlist, 0)) { ret = 1; goto restore; } diff --git a/Src/init.c b/Src/init.c index 87dd2e2..c537266 100644 --- a/Src/init.c +++ b/Src/init.c @@ -244,33 +244,24 @@ static int restricted; /**/ static void -parseargs(char **argv, char **runscript, char **cmdptr) +parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr) { char **x; LinkList paramlist; + int flags = PARSEARGS_TOPLEVEL; + if (**argv == '-') + flags |= PARSEARGS_LOGIN; argzero = posixzero = *argv++; SHIN = 0; - /* There's a bit of trickery with opts[INTERACTIVE] here. It starts * - * at a value of 2 (instead of 1) or 0. If it is explicitly set on * - * the command line, it goes to 1 or 0. If input is coming from * - * somewhere that normally makes the shell non-interactive, we do * - * "opts[INTERACTIVE] &= 1", so that only a *default* on state will * - * be changed. At the end of the function, a value of 2 gets * - * changed to 1. */ - opts[INTERACTIVE] = isatty(0) ? 2 : 0; /* - * MONITOR is similar: we initialise it to 2, and if it's - * still 2 at the end, we set it to the value of INTERACTIVE. + * parseopts sets up some options after we deal with emulation in + * order to be consistent --- the code in parseopts_setemulate() is + * matched by code at the end of the present function. */ - opts[MONITOR] = 2; /* may be unset in init_io() */ - opts[HASHDIRS] = 2; /* same relationship to INTERACTIVE */ - opts[USEZLE] = 1; /* see below, related to SHINSTDIN */ - opts[SHINSTDIN] = 0; - opts[SINGLECOMMAND] = 0; - if (parseopts(NULL, &argv, opts, cmdptr, NULL)) + if (parseopts(zsh_name, &argv, opts, cmdptr, NULL, flags)) exit(1); /* @@ -334,9 +325,45 @@ parseopts_insert(LinkList optlist, char *base, int optno) } /* + * This sets the global emulation plus the options we traditionally + * set immediately after that. This is just for historical consistency + * --- I don't think those options actually need to be set here. + */ +static void parseopts_setemulate(char *nam, int flags) +{ + emulate(nam, 1, &emulation, opts); /* initialises most options */ + opts[LOGINSHELL] = ((flags & PARSEARGS_LOGIN) != 0); + opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid()); + + /* There's a bit of trickery with opts[INTERACTIVE] here. It starts * + * at a value of 2 (instead of 1) or 0. If it is explicitly set on * + * the command line, it goes to 1 or 0. If input is coming from * + * somewhere that normally makes the shell non-interactive, we do * + * "opts[INTERACTIVE] &= 1", so that only a *default* on state will * + * be changed. At the end of the function, a value of 2 gets * + * changed to 1. */ + opts[INTERACTIVE] = isatty(0) ? 2 : 0; + /* + * MONITOR is similar: we initialise it to 2, and if it's + * still 2 at the end, we set it to the value of INTERACTIVE. + */ + opts[MONITOR] = 2; /* may be unset in init_io() */ + opts[HASHDIRS] = 2; /* same relationship to INTERACTIVE */ + opts[USEZLE] = 1; /* see below, related to SHINSTDIN */ + opts[SHINSTDIN] = 0; + opts[SINGLECOMMAND] = 0; +} + +/* * Parse shell options. - * If nam is not NULL, this is called from a command; don't - * exit on failure. + * + * If (flags & PARSEARGS_TOPLEVEL): + * - we are doing shell initilisation + * - nam is the name under which the shell was started + * - set up emulation and standard options based on that. + * Otherwise: + * - nam is a command name + * - don't exit on failure. * * If optlist is not NULL, it used to form a list of pointers * into new_opts indicating which options have been changed. @@ -345,23 +372,26 @@ parseopts_insert(LinkList optlist, char *base, int optno) /**/ mod_export int parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, - LinkList optlist) + LinkList optlist, int flags) { int optionbreak = 0; int action, optno; char **argv = *argvp; + int toplevel = ((flags & PARSEARGS_TOPLEVEL) != 0u); + int emulate_required = toplevel; + char *top_emulation = nam; *cmdp = 0; #define WARN_OPTION(F, S) \ do { \ - if (nam) \ + if (!toplevel) \ zwarnnam(nam, F, S); \ else \ zerr(F, S); \ } while (0) #define LAST_OPTION(N) \ do { \ - if (nam) { \ + if (!toplevel) { \ if (*argv) \ argv++; \ goto doneargv; \ @@ -381,7 +411,7 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, argv++; goto doneoptions; } - if (nam || *argv != args+1 || **argv != '-') + if (!toplevel || *argv != args+1 || **argv != '-') goto badoptionstring; /* GNU-style long options */ ++*argv; @@ -394,6 +424,19 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, printhelp(); LAST_OPTION(0); } + if (!strcmp(*argv, "emulate")) { + ++argv; + if (!*argv) { + zerr("--emulate: argument required"); + exit(1); + } + if (!emulate_required) { + zerr("--emulate: must precede other options"); + exit(1); + } + top_emulation = *argv; + break; + } /* `-' characters are allowed in long options */ for(args = *argv; *args; args++) if(*args == '-') @@ -402,9 +445,17 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, } if (unset(SHOPTIONLETTERS) && **argv == 'b') { + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } /* -b ends options at the end of this argument */ optionbreak = 1; } else if (**argv == 'c') { + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } /* -c command */ *cmdp = *argv; new_opts[INTERACTIVE] &= 1; @@ -417,15 +468,20 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, return 1; } longoptions: + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } if (!(optno = optlookup(*argv))) { WARN_OPTION("no such option: %s", *argv); return 1; - } else if (optno == RESTRICTED && !nam) { + } else if (optno == RESTRICTED && toplevel) { restricted = action; - } else if ((optno == EMACSMODE || optno == VIMODE) && nam) { + } else if ((optno == EMACSMODE || optno == VIMODE) && !toplevel) { WARN_OPTION("can't change option: %s", *argv); } else { - if (dosetopt(optno, action, !nam, new_opts) && nam) { + if (dosetopt(optno, action, toplevel, new_opts) && + !toplevel) { WARN_OPTION("can't change option: %s", *argv); } else if (optlist) { parseopts_insert(optlist, new_opts, optno); @@ -442,15 +498,21 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, } break; } else { + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } if (!(optno = optlookupc(**argv))) { WARN_OPTION("bad option: -%c", **argv); return 1; - } else if (optno == RESTRICTED && !nam) { + } else if (optno == RESTRICTED && toplevel) { restricted = action; - } else if ((optno == EMACSMODE || optno == VIMODE) && nam) { + } else if ((optno == EMACSMODE || optno == VIMODE) && + !toplevel) { WARN_OPTION("can't change option: %s", *argv); } else { - if (dosetopt(optno, action, !nam, new_opts) && nam) { + if (dosetopt(optno, action, toplevel, new_opts) && + !toplevel) { WARN_OPTION("can't change option: -%c", **argv); } else if (optlist) { parseopts_insert(optlist, new_opts, optno); @@ -470,6 +532,10 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, } doneargv: *argvp = argv; + if (emulate_required) { + parseopts_setemulate(top_emulation, flags); + emulate_required = 0; + } return 0; } @@ -1660,11 +1726,9 @@ zsh_main(UNUSED(int argc), char **argv) fdtable[0] = fdtable[1] = fdtable[2] = FDT_EXTERNAL; createoptiontable(); - emulate(zsh_name, 1, &emulation, opts); /* initialises most options */ - opts[LOGINSHELL] = (**argv == '-'); - opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid()); - /* sets ZLE, INTERACTIVE, SHINSTDIN and SINGLECOMMAND */ - parseargs(argv, &runscript, &cmd); + /* sets emulation, LOGINSHELL, PRIVILEGED, ZLE, INTERACTIVE, + * SHINSTDIN and SINGLECOMMAND */ + parseargs(zsh_name, argv, &runscript, &cmd); SHTTY = -1; init_io(cmd); diff --git a/Src/zsh.h b/Src/zsh.h index abe9a9c..1e982a6 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1361,6 +1361,14 @@ struct options { int argscount, argsalloc; }; +/* Flags to parseargs() */ + +enum { + PARSEARGS_TOPLEVEL = 0x1, /* Call to initialise shell */ + PARSEARGS_LOGIN = 0x2 /* Shell is login shell */ +}; + + /* * Handler arguments are: builtin name, null-terminated argument * list excluding command name, option structure, the funcid element from the diff --git a/Test/B07emulate.ztst b/Test/B07emulate.ztst index 2de097e..7b1592f 100644 --- a/Test/B07emulate.ztst +++ b/Test/B07emulate.ztst @@ -251,3 +251,28 @@ emulate sh -c '[[ a == a ]]' 0:regression test for POSIX_ALIASES reserved words F:Some reserved tokens are handled in alias expansion + + for mode in ksh bash zsh; do + $ZTST_testdir/../Src/zsh --emulate $mode -f -c 'emulate' + done +0:--emulate option +>ksh +>sh +>zsh + + $ZTST_testdir/../Src/zsh -f --emulate sh +1:--emulate must be first +*?*: --emulate: must precede other options + + $ZTST_testdir/../Src/zsh --emulate +1:--emulate needs an argument +*?*: --emulate: argument required + + for opt in shwordsplit noshwordsplit; do + $ZTST_testdir/../Src/zsh --emulate sh -f -o $opt -c ' + [[ -o shwordsplit ]] && echo yes || echo no + ' + done +0:--emulate followed by other options +>yes +>no ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Running "unset path" breaks PATH despite emulation being enabled 2017-09-08 11:30 ` Mikael Magnusson 2017-09-08 16:17 ` Peter Stephenson @ 2017-09-09 4:24 ` Eric Pruitt 1 sibling, 0 replies; 5+ messages in thread From: Eric Pruitt @ 2017-09-09 4:24 UTC (permalink / raw) To: zsh workers On Fri, Sep 08, 2017 at 01:30:05PM +0200, Mikael Magnusson wrote: > This works fine if you start zsh as sh though, ie [...] ARGV0=sh zsh For the benefit of other people who like myself, don't use actually Z shell, this is NOT the equivalent of "ARGV0=sh zsh" in many (most?) other shells, it's describing execve("sh", ["zsh", ...]): # For POSIX shells, you can use Z shell itself assuming there's not # a standardized built-in way I overlooked: $ zsh -c "ARGV0=sh zsh ..." # For Bash (and some others): $ (exec -a sh zsh ...) Eric ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-09-11 8:58 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-09-08 8:29 Running "unset path" breaks PATH despite emulation being enabled Eric Pruitt 2017-09-08 11:30 ` Mikael Magnusson 2017-09-08 16:17 ` Peter Stephenson 2017-09-11 8:58 ` Peter Stephenson 2017-09-09 4:24 ` Eric Pruitt
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).