diff options
Diffstat (limited to 'Src/exec.c')
-rw-r--r-- | Src/exec.c | 158 |
1 files changed, 83 insertions, 75 deletions
diff --git a/Src/exec.c b/Src/exec.c index 1ecbc3967..df915e152 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -448,10 +448,13 @@ zexecve(char *pth, char **argv, char **newenvp) else sprintf(buf + 2, "%s/%s", pwd, pth); zputenv(buf); +#ifndef FD_CLOEXEC closedumps(); +#endif if (newenvp == NULL) newenvp = environ; + winch_unblock(); execve(pth, argv, newenvp); /* If the execve returns (which in general shouldn't happen), * @@ -486,6 +489,7 @@ zexecve(char *pth, char **argv, char **newenvp) (pprog = pathprog(ptr2, NULL))) { argv[-2] = ptr2; argv[-1] = ptr + 1; + winch_unblock(); execve(pprog, argv - 2, newenvp); } zerr("%s: bad interpreter: %s: %e", pth, ptr2, @@ -494,13 +498,16 @@ zexecve(char *pth, char **argv, char **newenvp) *ptr = '\0'; argv[-2] = ptr2; argv[-1] = ptr + 1; + winch_unblock(); execve(ptr2, argv - 2, newenvp); } else { argv[-1] = ptr2; + winch_unblock(); execve(ptr2, argv - 1, newenvp); } } else if (eno == ENOEXEC) { argv[-1] = "sh"; + winch_unblock(); execve("/bin/sh", argv - 1, newenvp); } } else if (eno == ENOEXEC) { @@ -509,6 +516,7 @@ zexecve(char *pth, char **argv, char **newenvp) break; if (t0 == ct) { argv[-1] = "sh"; + winch_unblock(); execve("/bin/sh", argv - 1, newenvp); } } @@ -1019,6 +1027,11 @@ execstring(char *s, int dont_change_job, int exiting, char *context) Eprog prog; pushheap(); + if (isset(VERBOSE)) { + zputs(s, stderr); + fputc('\n', stderr); + fflush(stderr); + } if ((prog = parse_string(s, 0))) execode(prog, dont_change_job, exiting, context); popheap(); @@ -1079,6 +1092,9 @@ execsimple(Estate state) if (errflag) return (lastval = 1); + if (!isset(EXECOPT)) + return lastval = 0; + /* In evaluated traps, don't modify the line number. */ if (!IN_EVAL_TRAP() && !ineval && code) lineno = code - 1; @@ -1645,8 +1661,6 @@ execpline(Estate state, wordcode slcode, int how, int last1) return lastval; } -static int subsh_close = -1; - /* execute pipeline. This function assumes the `pline' is not NULL. */ /**/ @@ -1723,7 +1737,7 @@ execpline2(Estate state, wordcode pcode, } } else { /* otherwise just do the pipeline normally. */ - subsh_close = pipes[0]; + addfilelist(NULL, pipes[0]); execcmd(state, input, pipes[1], how, 0); } zclose(pipes[1]); @@ -1736,8 +1750,6 @@ execpline2(Estate state, wordcode pcode, execpline2(state, *state->pc++, how, pipes[0], output, last1); list_pipe = old_list_pipe; cmdpop(); - zclose(pipes[0]); - subsh_close = -1; } } @@ -1841,9 +1853,22 @@ quote_tokenized_output(char *str, FILE *file) case '*': case '?': case '$': + case ' ': putc('\\', file); break; + case '\t': + fputs("$'\\t'", file); + continue; + + case '\n': + fputs("$'\\n'", file); + continue; + + case '\r': + fputs("$'\\r'", file); + continue; + case '=': if (s == str) putc('\\', file); @@ -1885,7 +1910,14 @@ checkclobberparam(struct redir *f) return 0; } - if (!isset(CLOBBER) && (fd = (int)getintvalue(v)) && + /* + * We can't clobber the value in the parameter if it's + * already an opened file descriptor --- that means it's a decimal + * integer corresponding to an opened file descriptor, + * not merely an expression that evaluates to a file descriptor. + */ + if (!isset(CLOBBER) && (s = getstrvalue(v)) && + (fd = (int)zstrtol(s, &s, 10)) >= 0 && !*s && fd <= max_zsh_fd && fdtable[fd] == FDT_EXTERNAL) { zwarn("can't clobber parameter %s containing file descriptor %d", f->varid, fd); @@ -1935,7 +1967,7 @@ clobber_open(struct redir *f) /**/ static void -closemn(struct multio **mfds, int fd) +closemn(struct multio **mfds, int fd, int type) { if (fd >= 0 && mfds[fd] && mfds[fd]->ct >= 2) { struct multio *mn = mfds[fd]; @@ -1994,7 +2026,7 @@ closemn(struct multio **mfds, int fd) } } _exit(0); - } else if (fd >= 0) + } else if (fd >= 0 && type == REDIR_CLOSE) mfds[fd] = NULL; } @@ -2147,8 +2179,6 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag, mfds[fd1]->fds[mfds[fd1]->ct++] = fdN; } } - if (subsh_close >= 0 && fdtable[subsh_close] == FDT_UNUSED) - subsh_close = -1; } /**/ @@ -2847,9 +2877,6 @@ execcmd(Estate state, int input, int output, int how, int last1) close(synch[1]); read_loop(synch[0], &dummy, 1); close(synch[0]); -#ifdef PATH_DEV_FD - closem(FDT_PROC_SUBST); -#endif if (how & Z_ASYNC) { lastpid = (zlong) pid; /* indicate it's possible to set status for lastpid */ @@ -3066,7 +3093,7 @@ execcmd(Estate state, int input, int output, int how, int last1) } } if (fn->fd1 < 10) - closemn(mfds, fn->fd1); + closemn(mfds, fn->fd1, REDIR_CLOSE); if (!closed && zclose(fn->fd1) < 0) { zwarn("failed to close file descriptor %d: %e", fn->fd1, errno); @@ -3075,7 +3102,7 @@ execcmd(Estate state, int input, int output, int how, int last1) case REDIR_MERGEIN: case REDIR_MERGEOUT: if (fn->fd2 < 10) - closemn(mfds, fn->fd2); + closemn(mfds, fn->fd2, fn->type); if (!checkclobberparam(fn)) fil = -1; else if (fn->fd2 > 9 && @@ -3096,7 +3123,7 @@ execcmd(Estate state, int input, int output, int how, int last1) int fd = fn->fd2; if(fd == -2) fd = (fn->type == REDIR_MERGEOUT) ? coprocout : coprocin; - fil = dup(fd); + fil = movefd(dup(fd)); } if (fil == -1) { char fdstr[4]; @@ -3124,7 +3151,7 @@ execcmd(Estate state, int input, int output, int how, int last1) else fil = clobber_open(fn); if(fil != -1 && IS_ERROR_REDIR(fn->type)) - dfil = dup(fil); + dfil = movefd(dup(fil)); else dfil = 0; if (fil == -1 || dfil == -1) { @@ -3154,7 +3181,7 @@ execcmd(Estate state, int input, int output, int how, int last1) * spawning tee/cat processes as necessary. */ for (i = 0; i < 10; i++) if (mfds[i] && mfds[i]->ct >= 2) - closemn(mfds, i); + closemn(mfds, i, REDIR_CLOSE); if (nullexec) { if (nullexec == 1) { @@ -3233,33 +3260,12 @@ execcmd(Estate state, int input, int output, int how, int last1) if (is_shfunc) { /* It's a shell function */ - -#ifdef PATH_DEV_FD - int i; - - for (i = 10; i <= max_zsh_fd; i++) - if (fdtable[i] >= FDT_PROC_SUBST) - fdtable[i]++; -#endif - if (subsh_close >= 0) - zclose(subsh_close); - subsh_close = -1; - execshfunc((Shfunc) hn, args); -#ifdef PATH_DEV_FD - for (i = 10; i <= max_zsh_fd; i++) - if (fdtable[i] >= FDT_PROC_SUBST) - if (--(fdtable[i]) <= FDT_PROC_SUBST) - zclose(i); -#endif } else { /* It's a builtin */ if (forked) closem(FDT_INTERNAL); lastval = execbuiltin(args, (Builtin) hn); -#ifdef PATH_DEV_FD - closem(FDT_PROC_SUBST); -#endif fflush(stdout); if (save[1] == -2) { if (ferror(stdout)) { @@ -3329,9 +3335,6 @@ execcmd(Estate state, int input, int output, int how, int last1) DPUTS(varspc, "BUG: assignment before complex command"); list_pipe = 0; - if (subsh_close >= 0) - zclose(subsh_close); - subsh_close = -1; /* If we're forked (and we should be), no need to return */ DPUTS(last1 != 1 && !forked, "BUG: not exiting?"); DPUTS(type != WC_SUBSH, "Not sure what we're doing."); @@ -3874,9 +3877,7 @@ getoutputfile(char *cmd, char **eptr) untokenize(s); } - if (!jobtab[thisjob].filelist) - jobtab[thisjob].filelist = znewlinklist(); - zaddlinknode(jobtab[thisjob].filelist, nam); + addfilelist(nam, 0); if (!s) child_block(); @@ -3962,9 +3963,7 @@ getproc(char *cmd, char **eptr) return NULL; if (!(prog = parsecmd(cmd, eptr))) return NULL; - if (!jobtab[thisjob].filelist) - jobtab[thisjob].filelist = znewlinklist(); - zaddlinknode(jobtab[thisjob].filelist, ztrdup(pnam)); + addfilelist(pnam, 0); if ((pid = zfork(&bgtime))) { if (pid == -1) @@ -3982,7 +3981,7 @@ getproc(char *cmd, char **eptr) entersubsh(ESUB_ASYNC|ESUB_PGRP); redup(fd, out); #else /* PATH_DEV_FD */ - int pipes[2]; + int pipes[2], fd; if (thisjob == -1) return NULL; @@ -3999,7 +3998,9 @@ getproc(char *cmd, char **eptr) zclose(pipes[!out]); return NULL; } - fdtable[pipes[!out]] = FDT_PROC_SUBST; + fd = pipes[!out]; + fdtable[fd] = FDT_PROC_SUBST; + addfilelist(NULL, fd); if (!out) { addproc(pid, NULL, 1, &bgtime); @@ -4614,6 +4615,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) } starttrapscope(); + startpatternscope(); pptab = pparams; if (!(flags & PM_UNDEFINED)) @@ -4661,6 +4663,8 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) offptr++) opts[*offptr] = 0; } + /* All emulations start with pattern disables clear */ + clearpatterndisables(); } else restore_sticky = 0; @@ -4761,6 +4765,8 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) scriptname = oldscriptname; oflags = ooflags; + endpatternscope(); /* before restoring old LOCALPATTERNS */ + if (restore_sticky) { /* * If we switched to an emulation environment just for @@ -5070,7 +5076,6 @@ execsave(void) es->trapisfunc = trapisfunc; es->traplocallevel = traplocallevel; es->noerrs = noerrs; - es->subsh_close = subsh_close; es->underscore = ztrdup(zunderscore); es->next = exstack; exstack = es; @@ -5081,30 +5086,33 @@ execsave(void) void execrestore(void) { - struct execstack *en; + struct execstack *en = exstack; DPUTS(!exstack, "BUG: execrestore() without execsave()"); - list_pipe_pid = exstack->list_pipe_pid; - nowait = exstack->nowait; - pline_level = exstack->pline_level; - list_pipe_child = exstack->list_pipe_child; - list_pipe_job = exstack->list_pipe_job; - strcpy(list_pipe_text, exstack->list_pipe_text); - lastval = exstack->lastval; - noeval = exstack->noeval; - badcshglob = exstack->badcshglob; - cmdoutpid = exstack->cmdoutpid; - cmdoutval = exstack->cmdoutval; - use_cmdoutval = exstack->use_cmdoutval; - trap_return = exstack->trap_return; - trap_state = exstack->trap_state; - trapisfunc = exstack->trapisfunc; - traplocallevel = exstack->traplocallevel; - noerrs = exstack->noerrs; - subsh_close = exstack->subsh_close; - setunderscore(exstack->underscore); - zsfree(exstack->underscore); - en = exstack->next; - free(exstack); - exstack = en; + + queue_signals(); + exstack = exstack->next; + + list_pipe_pid = en->list_pipe_pid; + nowait = en->nowait; + pline_level = en->pline_level; + list_pipe_child = en->list_pipe_child; + list_pipe_job = en->list_pipe_job; + strcpy(list_pipe_text, en->list_pipe_text); + lastval = en->lastval; + noeval = en->noeval; + badcshglob = en->badcshglob; + cmdoutpid = en->cmdoutpid; + cmdoutval = en->cmdoutval; + use_cmdoutval = en->use_cmdoutval; + trap_return = en->trap_return; + trap_state = en->trap_state; + trapisfunc = en->trapisfunc; + traplocallevel = en->traplocallevel; + noerrs = en->noerrs; + setunderscore(en->underscore); + zsfree(en->underscore); + free(en); + + unqueue_signals(); } |