diff options
author | Peter Stephenson <p.w.stephenson@ntlworld.com> | 2017-08-15 20:49:23 +0100 |
---|---|---|
committer | Peter Stephenson <p.w.stephenson@ntlworld.com> | 2017-08-15 20:49:23 +0100 |
commit | ddb86759012992fa6471bd738f906a4ed434b69f (patch) | |
tree | 2400c5e08f28e9a6295ff0bf8005ebf849083583 /Src | |
parent | 74aff4106a4272d86c637c472a04efd46bbec07e (diff) | |
download | zsh-ddb86759012992fa6471bd738f906a4ed434b69f.tar.gz zsh-ddb86759012992fa6471bd738f906a4ed434b69f.tar.xz zsh-ddb86759012992fa6471bd738f906a4ed434b69f.zip |
posted but has not shown up: fix fd problem in subshell.
Record fd's that have been saved in fdtable and if the shell forks close them as they will never be restored.
Diffstat (limited to 'Src')
-rw-r--r-- | Src/exec.c | 18 | ||||
-rw-r--r-- | Src/zsh.h | 12 |
2 files changed, 27 insertions, 3 deletions
diff --git a/Src/exec.c b/Src/exec.c index f339dd6d0..9996dffed 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -972,7 +972,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 +1083,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(); @@ -2318,6 +2326,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; } } } @@ -3575,7 +3586,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 +4282,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); diff --git a/Src/zsh.h b/Src/zsh.h index ccd11db3d..91e8d7f8c 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -456,6 +456,18 @@ enum { #define FDT_PROC_SUBST 7 #endif +/* + * Mask to get the basic FDT type. + */ +#define FDT_TYPE_MASK 15 + +/* + * Bit flag that fd is saved for later restoration. + * Currently this is only use with FDT_INTERNAL. We use this fact so as + * not to have to mask checks against other types. + */ +#define FDT_SAVED_MASK 16 + /* Flags for input stack */ #define INP_FREE (1<<0) /* current buffer can be free'd */ #define INP_ALIAS (1<<1) /* expanding alias or history */ |