diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-06-27 05:33:04 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-06-27 05:33:04 +0000 |
commit | 346825df86466cf151be61b9429ef2c1734e66ea (patch) | |
tree | bd3e1ccd947b47f974c62b4113c5276416de2c9f /Src/exec.c | |
parent | a2159285e80508bb682d90a71270fbddada8bd05 (diff) | |
download | zsh-346825df86466cf151be61b9429ef2c1734e66ea.tar.gz zsh-346825df86466cf151be61b9429ef2c1734e66ea.tar.xz zsh-346825df86466cf151be61b9429ef2c1734e66ea.zip |
zsh-3.1.5-pws-24 zsh-3.1.5-pws-24
Diffstat (limited to 'Src/exec.c')
-rw-r--r-- | Src/exec.c | 154 |
1 files changed, 86 insertions, 68 deletions
diff --git a/Src/exec.c b/Src/exec.c index 5cfe3e3ef..5ae4f0d33 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -133,14 +133,17 @@ static int doneps4; /**/ List -parse_string(char *s) +parse_string(char *s, int ln) { List l; + int oldlineno = lineno; lexsave(); - inpush(s, 0, NULL); + inpush(s, (ln ? INP_LINENO : 0), NULL); strinbeg(0); + lineno = ln ? 1 : -1; l = parse_list(); + lineno = oldlineno; strinend(); inpop(); lexrestore(); @@ -301,7 +304,9 @@ execcursh(Cmd cmd, LinkList args, int flags) { if (!list_pipe) deletejob(jobtab + thisjob); + cmdpush(CS_CURSH); execlist(cmd->u.list, 1, flags & CFLAG_EXEC); + cmdpop(); return lastval; } @@ -354,7 +359,9 @@ zexecve(char *pth, char **argv) if (execvebuf[1] == '!') { for (t0 = 0; t0 != ct; t0++) if (execvebuf[t0] == '\n') - execvebuf[t0] = '\0'; + break; + while (inblank(execvebuf[t0])) + execvebuf[t0--] = '\0'; execvebuf[POUNDBANGLIMIT] = '\0'; for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++); for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++); @@ -676,7 +683,7 @@ execstring(char *s, int dont_change_job, int exiting) List list; pushheap(); - if ((list = parse_string(s))) + if ((list = parse_string(s, 0))) execlist(list, dont_change_job, exiting); popheap(); } @@ -694,8 +701,8 @@ execlist(List list, int dont_change_job, int exiting) { Sublist slist; static int donetrap; - int ret, cj; - int old_pline_level, old_list_pipe; + int ret, cj, csp; + int old_pline_level, old_list_pipe, oldlineno; /* * ERREXIT only forces the shell to exit if the last command in a && * or || fails. This is the case even if an earlier command is a @@ -707,6 +714,7 @@ execlist(List list, int dont_change_job, int exiting) cj = thisjob; old_pline_level = pline_level; old_list_pipe = list_pipe; + oldlineno = lineno; if (sourcelevel && unset(SHINSTDIN)) pline_level = list_pipe = 0; @@ -718,6 +726,7 @@ execlist(List list, int dont_change_job, int exiting) * called once for each sublist that fails. */ donetrap = 0; slist = list->left; + csp = cmdsp; /* Loop through code followed by &&, ||, or end of sublist. */ while (slist) { @@ -744,6 +753,7 @@ execlist(List list, int dont_change_job, int exiting) goto sublist_done; } } + cmdpush(CS_CMDAND); break; case ORNEXT: /* If the return code is zero, we skip pipelines until * @@ -760,12 +770,14 @@ execlist(List list, int dont_change_job, int exiting) goto sublist_done; } } + cmdpush(CS_CMDOR); break; } slist = slist->right; } sublist_done: + cmdsp = csp; noerrexit = oldnoerrexit; if (sigtrapped[SIGDEBUG]) @@ -794,6 +806,7 @@ sublist_done: pline_level = old_pline_level; list_pipe = old_list_pipe; + lineno = oldlineno; if (dont_change_job) thisjob = cj; } @@ -888,6 +901,9 @@ execpline(Sublist l, int how, int last1) DPUTS(!list_pipe_pid, "invalid list_pipe_pid"); addproc(list_pipe_pid, list_pipe_text); + if (!jn->procs->next) + jn->gleader = mypgrp; + for (pn = jobtab[jn->other].procs; pn; pn = pn->next) if (WIFSTOPPED(pn->status)) break; @@ -901,12 +917,14 @@ execpline(Sublist l, int how, int last1) jn->stat |= STAT_STOPPED | STAT_CHANGED; printjob(jn, !!isset(LONGLISTJOBS), 1); } - else + else if (newjob != list_pipe_job) deletejob(jn); + else + lastwj = -1; } for (; !nowait;) { - if (list_pipe_child) { + if (list_pipe_child || pline_level) { jn->stat |= STAT_NOPRINT; makerunning(jn); } @@ -917,8 +935,11 @@ execpline(Sublist l, int how, int last1) jn->stat & STAT_DONE && lastval2 & 0200) killpg(mypgrp, lastval2 & ~0200); - if ((list_pipe || last1) && !list_pipe_child && - jn->stat & STAT_STOPPED) { + if ((list_pipe || last1 || pline_level) && + !list_pipe_child && + ((jn->stat & STAT_STOPPED) || + (list_pipe_job && pline_level && + (jobtab[list_pipe_job].stat & STAT_STOPPED)))) { pid_t pid; int synch[2]; @@ -944,21 +965,28 @@ execpline(Sublist l, int how, int last1) close(synch[1]); read(synch[0], &dummy, 1); close(synch[0]); - jobtab[list_pipe_job].other = newjob; - jobtab[list_pipe_job].stat |= STAT_SUPERJOB; - jn->stat |= STAT_SUBJOB | STAT_NOPRINT; - jn->other = pid; - killpg(jobtab[list_pipe_job].gleader, SIGSTOP); + /* If this job has finished, we leave it as a + * normal (non-super-) job. */ + if (!(jn->stat & STAT_DONE)) { + jobtab[list_pipe_job].other = newjob; + jobtab[list_pipe_job].stat |= STAT_SUPERJOB; + jn->stat |= STAT_SUBJOB | STAT_NOPRINT; + jn->other = pid; + } + if ((list_pipe || last1) && jobtab[list_pipe_job].procs) + killpg(jobtab[list_pipe_job].gleader, SIGSTOP); break; } else { close(synch[0]); entersubsh(Z_ASYNC, 0, 0); - setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader); + if (jobtab[list_pipe_job].procs) + setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader); close(synch[1]); kill(getpid(), SIGSTOP); list_pipe = 0; list_pipe_child = 1; + opts[INTERACTIVE] = 0; break; } } @@ -975,7 +1003,8 @@ execpline(Sublist l, int how, int last1) jn->stat |= STAT_NOPRINT; killjb(jobtab + pj, lastval & ~0200); } - if (list_pipe_child || (list_pipe && (jn->stat & STAT_DONE))) + if (list_pipe_child || ((list_pipe || pline_level) && + (jn->stat & STAT_DONE))) deletejob(jn); thisjob = pj; @@ -998,19 +1027,19 @@ execpline2(Pline pline, int how, int input, int output, int last1) { pid_t pid; int pipes[2]; - int oldlineno; if (breaks || retflag) return; - oldlineno = lineno; - lineno = pline->left->lineno; + if (pline->left->lineno >= 0) + lineno = pline->left->lineno; - if (pline_level == 1) + if (pline_level == 1) { if (!sfcontext) strcpy(list_pipe_text, getjobtext((void *) pline->left)); else list_pipe_text[0] = '\0'; + } if (pline->type == END) execcmd(pline->left, input, output, how, last1 ? 1 : 2); else { @@ -1054,15 +1083,15 @@ execpline2(Pline pline, int how, int input, int output, int last1) if (pline->right) { /* if another execpline() is invoked because the command is * * a list it must know that we're already in a pipeline */ + cmdpush(CS_PIPE); list_pipe = 1; execpline2(pline->right, how, pipes[0], output, last1); list_pipe = old_list_pipe; + cmdpop(); zclose(pipes[0]); subsh_close = -1; } } - - lineno = oldlineno; } /* make the argv array */ @@ -1079,7 +1108,7 @@ makecline(LinkList list) argv = 2 + (char **) ncalloc((countlinknodes(list) + 4) * sizeof(char *)); if (isset(XTRACE)) { if (!doneps4) - fprintf(stderr, "%s", (prompt4) ? prompt4 : ""); + printprompt4(); for (node = firstnode(list); node; incnode(node)) { *ptr++ = (char *)getdata(node); @@ -1283,7 +1312,7 @@ addvars(LinkList l, int export) xtr = isset(XTRACE); if (xtr && nonempty(l)) { - fprintf(stderr, "%s", prompt4 ? prompt4 : ""); + printprompt4(); doneps4 = 1; } @@ -2179,8 +2208,9 @@ entersubsh(int how, int cl, int fake) attachtty(jobtab[thisjob].gleader); } } - else if (!jobtab[thisjob].gleader || - (setpgrp(0L, jobtab[thisjob].gleader) == -1)) { + else if (!(list_pipe || list_pipe_child || pline_level > 1) && + (!jobtab[thisjob].gleader || + setpgrp(0L, jobtab[thisjob].gleader) == -1)) { jobtab[thisjob].gleader = getpid(); if (list_pipe_job != thisjob && !jobtab[list_pipe_job].gleader) @@ -2322,7 +2352,7 @@ getoutput(char *cmd, int qt) Cmd c; Redir r; - if (!(list = parse_string(cmd))) + if (!(list = parse_string(cmd, 0))) return NULL; if (list != &dummy_list && !list->right && !list->left->flags && list->left->type == END && list->left->left->type == END && @@ -2451,7 +2481,7 @@ parsecmd(char *cmd) return NULL; } *str = '\0'; - if (str[1] || !(list = parse_string(cmd + 2))) { + if (str[1] || !(list = parse_string(cmd + 2, 0))) { zerr("parse error in process substitution", NULL, 0); return NULL; } @@ -2661,7 +2691,8 @@ execcond(Cmd cmd, LinkList args, int flags) { int stat; if (isset(XTRACE)) { - fprintf(stderr, "%s[[", prompt4 ? prompt4 : ""); + printprompt4(); + fprintf(stderr, "[["); tracingcond++; } stat = !evalcond(cmd->u.cond); @@ -2682,8 +2713,10 @@ execarith(Cmd cmd, LinkList args, int flags) char *e; zlong val = 0; - if (isset(XTRACE)) - fprintf(stderr, "%s((", prompt4 ? prompt4 : ""); + if (isset(XTRACE)) { + printprompt4(); + fprintf(stderr, "(("); + } if (args) while ((e = (char *) ugetnode(args))) { if (isset(XTRACE)) @@ -2759,21 +2792,22 @@ static void execshfunc(Cmd cmd, Shfunc shf, LinkList args) { LinkList last_file_list = NULL; + unsigned char *ocs; + int ocsp; if (errflag) return; - if (!list_pipe) { + if (!list_pipe && thisjob != list_pipe_job) { /* Without this deletejob the process table * * would be filled by a recursive function. */ last_file_list = jobtab[thisjob].filelist; jobtab[thisjob].filelist = NULL; deletejob(jobtab + thisjob); } - if (isset(XTRACE)) { LinkNode lptr; - fprintf(stderr, "%s", prompt4 ? prompt4 : prompt4); + printprompt4(); if (args) for (lptr = firstnode(args); lptr; incnode(lptr)) { if (lptr != firstnode(args)) @@ -2783,8 +2817,14 @@ execshfunc(Cmd cmd, Shfunc shf, LinkList args) fputc('\n', stderr); fflush(stderr); } - + ocs = cmdstack; + ocsp = cmdsp; + cmdstack = (unsigned char *) zalloc(CMDSTACKSZ); + cmdsp = 0; doshfunc(shf->nam, shf->funcdef, args, shf->flags, 0); + free(cmdstack); + cmdstack = ocs; + cmdsp = ocsp; if (!list_pipe) deletefilelist(last_file_list); @@ -2842,9 +2882,8 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval) * was executed. */ { char **tab, **x, *oargv0 = NULL; - int xexittr, newexittr, oldzoptind, oldlastval; - void *xexitfn, *newexitfn; - char saveopts[OPT_SIZE]; + int oldzoptind, oldlastval; + char saveopts[OPT_SIZE], *oldscriptname; int obreaks = breaks; HEAPALLOC { @@ -2852,14 +2891,12 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval) if (trapreturn < 0) trapreturn--; oldlastval = lastval; - xexittr = sigtrapped[SIGEXIT]; - if (xexittr & ZSIG_FUNC) - xexitfn = shfunctab->removenode(shfunctab, "TRAPEXIT"); - else - xexitfn = sigfuncs[SIGEXIT]; - sigtrapped[SIGEXIT] = 0; - sigfuncs[SIGEXIT] = NULL; + + starttrapscope(); + tab = pparams; + oldscriptname = scriptname; + scriptname = name; oldzoptind = zoptind; zoptind = 1; @@ -2902,6 +2939,7 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval) argzero = oargv0; } zoptind = oldzoptind; + scriptname = oldscriptname; pparams = tab; if (isset(LOCALOPTIONS)) { @@ -2916,27 +2954,7 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval) opts[LOCALOPTIONS] = saveopts[LOCALOPTIONS]; } - /* - * The trap '...' EXIT runs in the environment of the caller, - * so remember it here but run it after resetting the - * traps for the parent. - */ - newexittr = sigtrapped[SIGEXIT]; - newexitfn = sigfuncs[SIGEXIT]; - if (newexittr & ZSIG_FUNC) - shfunctab->removenode(shfunctab, "TRAPEXIT"); - - sigtrapped[SIGEXIT] = xexittr; - if (xexittr & ZSIG_FUNC) { - shfunctab->addnode(shfunctab, ztrdup("TRAPEXIT"), xexitfn); - sigfuncs[SIGEXIT] = ((Shfunc) xexitfn)->funcdef; - } else - sigfuncs[SIGEXIT] = (List) xexitfn; - - if (newexitfn) { - dotrapargs(SIGEXIT, &newexittr, newexitfn); - freestruct(newexitfn); - } + endtrapscope(); if (trapreturn < -1) trapreturn++; @@ -3008,7 +3026,7 @@ getfpfunc(char *s) d[len] = '\0'; d = metafy(d, len, META_REALLOC); HEAPALLOC { - r = parse_string(d); + r = parse_string(d, 1); } LASTALLOC; return r; } else |