diff options
author | Axel Beckert <abe@deuxchevaux.org> | 2017-09-12 23:22:34 +0200 |
---|---|---|
committer | Axel Beckert <abe@deuxchevaux.org> | 2017-09-12 23:22:34 +0200 |
commit | 4aaf06e6678dcead65d7226bd6bde3cffeb2cb2e (patch) | |
tree | 5c8e2ac2c9a85e2e6568aed7120372e6efa074ac /Src/exec.c | |
parent | f33de64abf57611e59df72da230f3d0d6760c4c5 (diff) | |
parent | 6ff4787e830f8edb3a7e32490a88a131e4b62f7f (diff) | |
download | zsh-4aaf06e6678dcead65d7226bd6bde3cffeb2cb2e.tar.gz zsh-4aaf06e6678dcead65d7226bd6bde3cffeb2cb2e.zip |
Merge tag 'zsh-5.4.2' into debian
Release 5.4.2
Diffstat (limited to 'Src/exec.c')
-rw-r--r-- | Src/exec.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/Src/exec.c b/Src/exec.c index f339dd6d0..cd99733f1 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -41,12 +41,15 @@ enum { ADDVAR_RESTORE = 1 << 2 }; -/* used to suppress ERREXIT and trapping of SIGZERR, SIGEXIT. */ +/* + * used to suppress ERREXIT and trapping of SIGZERR, SIGEXIT. + * Bits from noerrexit_bits. + */ /**/ int noerrexit; -/* used to suppress ERREXIT for one occurrence */ +/* used to suppress ERREXIT or ERRRETURN for one occurrence: 0 or 1 */ /**/ int this_noerrexit; @@ -972,7 +975,7 @@ enum { static void entersubsh(int flags) { - int sig, monitor, job_control_ok; + int i, sig, monitor, job_control_ok; if (!(flags & ESUB_KEEPTRAP)) for (sig = 0; sig < SIGCOUNT; sig++) @@ -1083,6 +1086,14 @@ entersubsh(int flags) opts[MONITOR] = 0; opts[USEZLE] = 0; zleactive = 0; + /* + * If we've saved fd's for later restoring, we're never going + * to restore them now, so just close them. + */ + for (i = 10; i <= max_zsh_fd; i++) { + if (fdtable[i] & FDT_SAVED_MASK) + zclose(i); + } if (flags & ESUB_PGRP) clearjobtab(monitor); get_usage(); @@ -1291,7 +1302,7 @@ execlist(Estate state, int dont_change_job, int exiting) int oerrexit_opt = opts[ERREXIT]; Param pm; opts[ERREXIT] = 0; - noerrexit = 1; + noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; if (ltype & Z_SIMPLE) /* skip the line number */ pc2++; pm = setsparam("ZSH_DEBUG_CMD", getpermtext(state->prog, pc2, 0)); @@ -1343,13 +1354,13 @@ execlist(Estate state, int dont_change_job, int exiting) int isend = (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END); next = state->pc + WC_SUBLIST_SKIP(code); if (!oldnoerrexit) - noerrexit = !isend; + noerrexit = isend ? 0 : NOERREXIT_EXIT | NOERREXIT_RETURN; if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT) { /* suppress errexit for "! this_command" */ if (isend) this_noerrexit = 1; /* suppress errexit for ! <list-of-shell-commands> */ - noerrexit = 1; + noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; } switch (WC_SUBLIST_TYPE(code)) { case WC_SUBLIST_END: @@ -1436,11 +1447,11 @@ sublist_done: /* * See hairy code near the end of execif() for the - * following. "noerrexit == 2" only applies until + * following. "noerrexit " only applies until * we hit execcmd on the way down. We're now * on the way back up, so don't restore it. */ - if (oldnoerrexit != 2) + if (!(oldnoerrexit & NOERREXIT_UNTIL_EXEC)) noerrexit = oldnoerrexit; if (sigtrapped[SIGDEBUG] && !isset(DEBUGBEFORECMD) && !donedebug) { @@ -1450,7 +1461,7 @@ sublist_done: */ int oerrexit_opt = opts[ERREXIT]; opts[ERREXIT] = 0; - noerrexit = 1; + noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; exiting = donetrap; ret = lastval; dotrap(SIGDEBUG); @@ -1466,16 +1477,19 @@ sublist_done: /* Check whether we are suppressing traps/errexit * * (typically in init scripts) and if we haven't * * already performed them for this sublist. */ - if (!noerrexit && !this_noerrexit && !donetrap && !this_donetrap) { - if (sigtrapped[SIGZERR] && lastval) { + if (!this_noerrexit && !donetrap && !this_donetrap) { + if (sigtrapped[SIGZERR] && lastval && + !(noerrexit & NOERREXIT_EXIT)) { dotrap(SIGZERR); donetrap = 1; } if (lastval) { int errreturn = isset(ERRRETURN) && - (isset(INTERACTIVE) || locallevel || sourcelevel); - int errexit = isset(ERREXIT) || - (isset(ERRRETURN) && !errreturn); + (isset(INTERACTIVE) || locallevel || sourcelevel) && + !(noerrexit & NOERREXIT_RETURN); + int errexit = (isset(ERREXIT) || + (isset(ERRRETURN) && !errreturn)) && + !(noerrexit & NOERREXIT_EXIT); if (errexit) { if (sigtrapped[SIGEXIT]) dotrap(SIGEXIT); @@ -2318,6 +2332,9 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag, return; } save[fd1] = fdN; + DPUTS(fdtable[fdN] != FDT_INTERNAL, + "Saved file descriptor not marked as internal"); + fdtable[fdN] |= FDT_SAVED_MASK; } } } @@ -3008,7 +3025,7 @@ execcmd_exec(Estate state, Execcmd_params eparams, preargs = NULL; /* if we get this far, it is OK to pay attention to lastval again */ - if (noerrexit == 2 && !is_shfunc) + if ((noerrexit & NOERREXIT_UNTIL_EXEC) && !is_shfunc) noerrexit = 0; /* Do prefork substitutions. @@ -3575,7 +3592,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, } if (!bad && fn->fd1 <= max_zsh_fd) { if (fn->fd1 >= 10 && - fdtable[fn->fd1] == FDT_INTERNAL) + (fdtable[fn->fd1] & FDT_TYPE_MASK) == + FDT_INTERNAL) bad = 3; } } @@ -4270,7 +4288,7 @@ closem(int how) for (i = 10; i <= max_zsh_fd; i++) if (fdtable[i] != FDT_UNUSED && - (how == FDT_UNUSED || fdtable[i] == how)) { + (how == FDT_UNUSED || (fdtable[i] & FDT_TYPE_MASK) == how)) { if (i == SHTTY) SHTTY = -1; zclose(i); @@ -5450,6 +5468,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) char saveopts[OPT_SIZE], *oldscriptname = scriptname; char *name = shfunc->node.nam; int flags = shfunc->node.flags, ooflags; + int savnoerrexit; char *fname = dupstring(name); int obreaks, ocontflag, oloops, saveemulation, restore_sticky; Eprog prog; @@ -5472,6 +5491,11 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) trap_return--; oldlastval = lastval; oldnumpipestats = numpipestats; + savnoerrexit = noerrexit; + /* + * Suppression of ERR_RETURN is turned off in function scope. + */ + noerrexit &= ~NOERREXIT_RETURN; if (noreturnval) { /* * Easiest to use the heap here since we're bracketed @@ -5690,6 +5714,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) if (trap_state == TRAP_STATE_PRIMED) trap_return++; ret = lastval; + noerrexit = savnoerrexit; if (noreturnval) { lastval = oldlastval; numpipestats = oldnumpipestats; |