void evalstring(char *s, int flags) { union node *n; struct stackmark smark; int flags_exit; int any; flags_exit = flags & EV_EXIT; flags &= ~EV_EXIT; any = 0; setstackmark(&smark); setinputstring(s, 1); while ((n = parsecmd(0)) != NEOF) { if (n != NULL && !nflag) { if (flags_exit && preadateof()) evaltree(n, flags | EV_EXIT); else evaltree(n, flags); any = 1; } popstackmark(&smark); setstackmark(&smark); } popfile(); popstackmark(&smark); if (!any) exitstatus = 0; if (flags_exit) exraise(EXEXIT); }
static union node * evalcase(union node *n) { union node *cp; union node *patp; struct arglist arglist; struct stackmark smark; setstackmark(&smark); arglist.lastp = &arglist.list; oexitstatus = exitstatus; expandarg(n->ncase.expr, &arglist, EXP_TILDE); for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) { for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) { if (casematch(patp, arglist.list->text)) { popstackmark(&smark); while (cp->nclist.next && cp->type == NCLISTFALLTHRU && cp->nclist.body == NULL) cp = cp->nclist.next; if (cp->nclist.next && cp->type == NCLISTFALLTHRU) return (cp); if (cp->nclist.body == NULL) exitstatus = 0; return (cp->nclist.body); } } } popstackmark(&smark); exitstatus = 0; return (NULL); }
void evalstring(char *s, int flags) { union node *n; struct stackmark smark; int flags_exit; flags_exit = flags & EV_EXIT; flags &= ~EV_EXIT; setstackmark(&smark); setinputstring(s, 1); while ((n = parsecmd(0)) != NEOF) { if (n != NULL) { if (flags_exit && preadateof()) evaltree(n, flags | EV_EXIT); else evaltree(n, flags); } popstackmark(&smark); } popfile(); popstackmark(&smark); if (flags_exit) exitshell(exitstatus); }
void cmdloop(int top) { union node *n; struct stackmark smark; int inter; int numeof = 0; enum skipstate skip; TRACE(("cmdloop(%d) called\n", top)); setstackmark(&smark); for (;;) { if (pendingsigs) dotrap(); inter = 0; if (iflag == 1 && top) { inter = 1; showjobs(out2, SHOW_CHANGED); chkmail(0); flushout(&errout); nflag = 0; } n = parsecmd(inter); TRACE(("cmdloop: "); showtree(n)); /* showtree(n); DEBUG */ if (n == NEOF) { if (!top || numeof >= 50) break; if (nflag) break; if (!stoppedjobs()) { if (!iflag || !Iflag) break; out2str("\nUse \"exit\" to leave shell.\n"); } numeof++; } else if (n != NULL && nflag == 0) { job_warning = (job_warning == 2) ? 1 : 0; numeof = 0; evaltree(n, EV_MORE); } popstackmark(&smark); setstackmark(&smark); /* * Any SKIP* can occur here! SKIP(FUNC|BREAK|CONT) occur when * a dotcmd is in a loop or a function body and appropriate * built-ins occurs in file scope in the sourced file. Values * other than SKIPFILE are reset by the appropriate eval*() * that contained the dotcmd() call. */ skip = current_skipstate(); if (skip != SKIPNONE) { if (skip == SKIPFILE) stop_skipping(); break; } } popstackmark(&smark); }
void evalstring(char *s) { union node *n; struct stackmark smark; setstackmark(&smark); setinputstring(s, 1); while ((n = parsecmd(0)) != NEOF) { evaltree(n, 0); popstackmark(&smark); } popfile(); popstackmark(&smark); }
static void cmdloop(int top) { union node *n; struct stackmark smark; int inter; int numeof = 0; TRACE(("cmdloop(%d) called\n", top)); setstackmark(&smark); for (;;) { if (pendingsig) dotrap(); inter = 0; if (iflag && top) { inter++; showjobs(1, SHOWJOBS_DEFAULT); #ifndef CBSD chkmail(0); #endif flushout(&output); } n = parsecmd(inter); /* showtree(n); DEBUG */ if (n == NEOF) { if (!top || numeof >= 50) break; if (!stoppedjobs()) { if (!Iflag) break; out2fmt_flush("\nUse \"exit\" to leave shell.\n"); } numeof++; } else if (n != NULL && nflag == 0) { job_warning = (job_warning == 2) ? 1 : 0; numeof = 0; evaltree(n, 0); } popstackmark(&smark); setstackmark(&smark); if (evalskip != 0) { if (evalskip == SKIPRETURN) evalskip = 0; break; } } popstackmark(&smark); }
int dotcmd(int argc, char **argv) { exitstatus = 0; if (argc >= 2) { /* That's what SVR2 does */ char *fullname; /* * dot_funcnest needs to be 0 when not in a dotcmd, so it * cannot be restored with (funcnest + 1). */ int dot_funcnest_old; struct stackmark smark; setstackmark(&smark); fullname = find_dot_file(argv[1]); setinputfile(fullname, 1); commandname = fullname; dot_funcnest_old = dot_funcnest; dot_funcnest = funcnest + 1; cmdloop(0); dot_funcnest = dot_funcnest_old; popfile(); popstackmark(&smark); } return exitstatus; }
static void evalcase(union node *n, int flags) { union node *cp; union node *patp; struct arglist arglist; struct stackmark smark; setstackmark(&smark); arglist.lastp = &arglist.list; oexitstatus = exitstatus; exitstatus = 0; expandarg(n->ncase.expr, &arglist, EXP_TILDE); for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) { for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) { if (casematch(patp, arglist.list->text)) { if (evalskip == 0) { evaltree(cp->nclist.body, flags); } goto out; } } } out: popstackmark(&smark); }
STATIC void evalcase(shinstance *psh, union node *n, int flags) { union node *cp; union node *patp; struct arglist arglist; struct stackmark smark; int status = 0; setstackmark(psh, &smark); arglist.lastp = &arglist.list; expandarg(psh, n->ncase.expr, &arglist, EXP_TILDE); for (cp = n->ncase.cases ; cp && psh->evalskip == 0 ; cp = cp->nclist.next) { for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) { if (casematch(psh, patp, arglist.list->text)) { if (psh->evalskip == 0) { evaltree(psh, cp->nclist.body, flags); status = psh->exitstatus; } goto out; } } } out: psh->exitstatus = status; popstackmark(psh, &smark); }
void evalstring(shinstance *psh, char *s, int flag) { union node *n; struct stackmark smark; setstackmark(psh, &smark); setinputstring(psh, s, 1); while ((n = parsecmd(psh, 0)) != NEOF) { evaltree(psh, n, flag); popstackmark(psh, &smark); } popfile(psh); popstackmark(psh, &smark); }
static void evalfor(union node *n, int flags) { struct arglist arglist; union node *argp; struct strlist *sp; struct stackmark smark; setstackmark(&smark); arglist.lastp = &arglist.list; for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { oexitstatus = exitstatus; expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); } *arglist.lastp = NULL; exitstatus = 0; loopnest++; for (sp = arglist.list ; sp ; sp = sp->next) { setvar(n->nfor.var, sp->text, 0); evaltree(n->nfor.body, flags); if (evalskip) { if (evalskip == SKIPCONT && --skipcount <= 0) { evalskip = 0; continue; } if (evalskip == SKIPBREAK && --skipcount <= 0) evalskip = 0; break; } } loopnest--; popstackmark(&smark); }
void cmdloop(struct shinstance *psh, int top) { union node *n; struct stackmark smark; int inter; int numeof = 0; TRACE((psh, "cmdloop(%d) called\n", top)); setstackmark(psh, &smark); for (;;) { if (psh->pendingsigs) dotrap(psh); inter = 0; if (iflag(psh) && top) { inter = 1; showjobs(psh, psh->out2, SHOW_CHANGED); chkmail(psh, 0); flushout(&psh->errout); } n = parsecmd(psh, inter); /* showtree(n); DEBUG */ if (n == NEOF) { if (!top || numeof >= 50) break; if (!stoppedjobs(psh)) { if (!Iflag(psh)) break; out2str(psh, "\nUse \"exit\" to leave shell.\n"); } numeof++; } else if (n != NULL && nflag(psh) == 0) { psh->job_warning = (psh->job_warning == 2) ? 1 : 0; numeof = 0; evaltree(psh, n, 0); } popstackmark(psh, &smark); setstackmark(psh, &smark); if (psh->evalskip == SKIPFILE) { psh->evalskip = 0; break; } } popstackmark(psh, &smark); }
void cmdloop(int top) { union node *n; struct stackmark smark; int inter; int numeof = 0; TRACE(("cmdloop(%d) called\n", top)); setstackmark(&smark); for (;;) { if (pendingsigs) dotrap(); inter = 0; if (iflag && top) { inter = 1; showjobs(out2, SHOW_CHANGED); chkmail(0); flushout(&errout); } n = parsecmd(inter); /* showtree(n); DEBUG */ if (n == NEOF) { if (!top || numeof >= 50) break; if (!stoppedjobs()) { if (!Iflag) break; out2str("\nUse \"exit\" to leave shell.\n"); } numeof++; } else if (n != NULL && nflag == 0) { job_warning = (job_warning == 2) ? 1 : 0; numeof = 0; evaltree(n, 0); } popstackmark(&smark); setstackmark(&smark); if (evalskip == SKIPFILE) { evalskip = 0; break; } } popstackmark(&smark); }
void evalstring(char *s, int flag) { union node *n; struct stackmark smark; setstackmark(&smark); setinputstring(s, 1); while ((n = parsecmd(0)) != NEOF) { TRACE(("evalstring: "); showtree(n)); if (nflag == 0) evaltree(n, flag); popstackmark(&smark); } popfile(); popstackmark(&smark); }
void evalbackcmd(union node *n, struct backcmd *result) { int pip[2]; struct job *jp; struct stackmark smark; /* unnecessary */ setstackmark(&smark); result->fd = -1; result->buf = NULL; result->nleft = 0; result->jp = NULL; if (nflag || n == NULL) { goto out; } #ifdef notyet /* * For now we disable executing builtins in the same * context as the shell, because we are not keeping * enough state to recover from changes that are * supposed only to affect subshells. eg. echo "`cd /`" */ if (n->type == NCMD) { exitstatus = oexitstatus; evalcommand(n, EV_BACKCMD, result); } else #endif { INTOFF; if (sh_pipe(pip) < 0) error("Pipe call failed"); jp = makejob(n, 1); if (forkshell(jp, n, FORK_NOJOB) == 0) { FORCEINTON; close(pip[0]); if (pip[1] != 1) { close(1); copyfd(pip[1], 1, 1, 0); close(pip[1]); } eflag = 0; evaltree(n, EV_EXIT); /* NOTREACHED */ } close(pip[1]); result->fd = pip[0]; result->jp = jp; INTON; } out: popstackmark(&smark); TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", result->fd, result->buf, result->nleft, result->jp)); }
void chkmail(void) { const char *mpath; char *p; char *q; time_t *mtp; struct stackmark smark; #ifdef WINDOWS struct stat statb; #else struct stat64 statb; #endif setstackmark(&smark); mpath = mpathset() ? mpathval() : mailval(); for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) { p = padvance(&mpath, nullstr); if (p == NULL) break; if (*p == '\0') continue; for (q = p ; *q ; q++); #ifdef DEBUG if (q[-1] != '/') abort(); #endif q[-1] = '\0'; /* delete trailing '/' */ #ifdef WINDOWS if (stat(p, &statb) < 0) { #else if (stat64(p, &statb) < 0) { #endif *mtp = 0; continue; } if (!changed && statb.st_mtime != *mtp) { outfmt( &errout, snlfmt, pathopt ? pathopt : "you have mail" ); } *mtp = statb.st_mtime; } changed = 0; popstackmark(&smark); } void changemail(const char *val) { changed++; }
static int cmdloop(int top) { union node *n; struct stackmark smark; int inter; int status = 0; int numeof = 0; TRACE(("cmdloop(%d) called\n", top)); #ifdef HETIO if(iflag && top) hetio_init(); #endif for (;;) { int skip; setstackmark(&smark); if (jobctl) showjobs(out2, SHOW_CHANGED); inter = 0; if (iflag && top) { inter++; chkmail(); } n = parsecmd(inter); /* showtree(n); DEBUG */ if (n == NEOF) { if (!top || numeof >= 50) break; if (!stoppedjobs()) { if (!Iflag) break; out2str("\nUse \"exit\" to leave shell.\n"); } numeof++; } else if (nflag == 0) { job_warning = (job_warning == 2) ? 1 : 0; numeof = 0; evaltree(n, 0); status = exitstatus; } popstackmark(&smark); skip = evalskip; if (skip) { evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); break; } } return status; }
void chkmail(int32_t silent) { int32_t i; const_cstring_t mpath; cstring_t p; cstring_t q; struct stackmark smark; struct stat statb; if (silent) nmboxes = 10; if (nmboxes == 0) return; setstackmark(&smark); mpath = mpathset() ? mpathval() : mailval(); for (i = 0 ; i < nmboxes ; i++) { p = padvance(&mpath, nullstr); if (p == NULL) break; if (*p == '\0') continue; for (q = p ; *q ; q++); if (q[-1] != '/') abort(); q[-1] = '\0'; /* delete trailing '/' */ #ifdef notdef /* this is what the System V shell claims to do (it lies) */ if (stat(p, &statb) < 0) statb.st_mtime = 0; if (statb.st_mtime > mailtime[i] && ! silent) { out2str(pathopt ? pathopt : "you have mail"); out2c('\n'); } mailtime[i] = statb.st_mtime; #else /* this is what it should do */ if (stat(p, &statb) < 0) statb.st_size = 0; if (statb.st_size > mailtime[i] && ! silent) { out2str(pathopt ? pathopt : "you have mail"); out2c('\n'); } mailtime[i] = statb.st_size; #endif } nmboxes = i; popstackmark(&smark); }
int32_t casematch(union node* pattern, const_cstring_t val) { struct stackmark smark; int32_t result; cstring_t p; setstackmark(&smark); argbackq = pattern->narg.backquote; STARTSTACKSTR(expdest); ifslastp = NULL; argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); STPUTC('\0', expdest); p = grabstackstr(expdest); result = patmatch(p, val, 0); popstackmark(&smark); return result; }
int casematch(union node *pattern, const char *val) { struct stackmark smark; int result; char *p; setstackmark(&smark); argbackq = pattern->narg.backquote; STARTSTACKSTR(expdest); argstr(pattern->narg.text, EXP_TILDE | EXP_CASE, NULL); STPUTC('\0', expdest); p = grabstackstr(expdest); result = patmatch(p, val); popstackmark(&smark); return result; }
int casematch(shinstance *psh, union node *pattern, char *val) { struct stackmark smark; int result; char *p; setstackmark(psh, &smark); psh->argbackq = pattern->narg.backquote; STARTSTACKSTR(psh, psh->expdest); psh->ifslastp = NULL; argstr(psh, pattern->narg.text, EXP_TILDE | EXP_CASE); STPUTC(psh, '\0', psh->expdest); p = grabstackstr(psh, psh->expdest); result = patmatch(psh, p, val, 0); popstackmark(psh, &smark); return result; }
arith_t arith(const char *s) { struct stackmark smark; arith_t result; setstackmark(&smark); arith_buf = arith_startbuf = s; result = assignment(yylex(), 0); if (last_token) yyerror("expecting EOF"); popstackmark(&smark); return result; }
int dotcmd(struct shinstance *psh, int argc, char **argv) { psh->exitstatus = 0; if (argc >= 2) { /* That's what SVR2 does */ char *fullname; struct stackmark smark; setstackmark(psh, &smark); fullname = find_dot_file(psh, argv[1]); setinputfile(psh, fullname, 1); psh->commandname = fullname; cmdloop(psh, 0); popfile(psh); popstackmark(psh, &smark); } return psh->exitstatus; }
int dotcmd(int argc, char **argv) { exitstatus = 0; if (argc >= 2) { /* That's what SVR2 does */ char *fullname; struct stackmark smark; setstackmark(&smark); fullname = find_dot_file(argv[1]); setinputfile(fullname, 1); commandname = fullname; cmdloop(0); popfile(); popstackmark(&smark); } return exitstatus; }
STATIC void evalfor(union node *n, int flags) { struct arglist arglist; union node *argp; struct strlist *sp; struct stackmark smark; int status; status = nflag ? exitstatus : 0; setstackmark(&smark); arglist.lastp = &arglist.list; for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); if (evalskip) goto out; } *arglist.lastp = NULL; loopnest++; for (sp = arglist.list ; sp ; sp = sp->next) { setvar(n->nfor.var, sp->text, 0); evaltree(n->nfor.body, flags & EV_TESTED); status = exitstatus; if (nflag) break; if (evalskip) { if (evalskip == SKIPCONT && --skipcount <= 0) { evalskip = SKIPNONE; continue; } if (evalskip == SKIPBREAK && --skipcount <= 0) evalskip = SKIPNONE; break; } } loopnest--; exitstatus = status; out: popstackmark(&smark); }
void evalbackcmd(union node *n, struct backcmd *result) { int pip[2]; struct job *jp; struct stackmark smark; /* unnecessary */ setstackmark(&smark); result->fd = -1; result->buf = NULL; result->nleft = 0; result->jp = NULL; if (n == NULL) { exitstatus = 0; goto out; } if (n->type == NCMD) { exitstatus = oexitstatus; evalcommand(n, EV_BACKCMD, result); } else { exitstatus = 0; if (pipe(pip) < 0) error("Pipe call failed: %s", strerror(errno)); jp = makejob(n, 1); if (forkshell(jp, n, FORK_NOJOB) == 0) { FORCEINTON; close(pip[0]); if (pip[1] != 1) { dup2(pip[1], 1); close(pip[1]); } evaltree(n, EV_EXIT); } close(pip[1]); result->fd = pip[0]; result->jp = jp; } out: popstackmark(&smark); TRACE(("evalbackcmd done: fd=%d buf=%p nleft=%d jp=%p\n", result->fd, result->buf, result->nleft, result->jp)); }
int evalstring(char *s, int flags) { union node *n; struct stackmark smark; int status; setinputstring(s); setstackmark(&smark); status = 0; while ((n = parsecmd(0)) != NEOF) { evaltree(n, flags); status = exitstatus; popstackmark(&smark); if (evalskip) break; } popfile(); return status; }
STATIC void evalfor(shinstance *psh, union node *n, int flags) { struct arglist arglist; union node *argp; struct strlist *sp; struct stackmark smark; int status = 0; setstackmark(psh, &smark); arglist.lastp = &arglist.list; for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { expandarg(psh, argp, &arglist, EXP_FULL | EXP_TILDE); if (psh->evalskip) goto out; } *arglist.lastp = NULL; psh->loopnest++; for (sp = arglist.list ; sp ; sp = sp->next) { setvar(psh, n->nfor.var, sp->text, 0); evaltree(psh, n->nfor.body, flags & EV_TESTED); status = psh->exitstatus; if (psh->evalskip) { if (psh->evalskip == SKIPCONT && --psh->skipcount <= 0) { psh->evalskip = 0; continue; } if (psh->evalskip == SKIPBREAK && --psh->skipcount <= 0) psh->evalskip = 0; break; } } psh->loopnest--; psh->exitstatus = status; out: popstackmark(psh, &smark); }
void evalbackcmd(union node *n, struct backcmd *result) { int pip[2]; struct job *jp; struct stackmark smark; struct jmploc jmploc; struct jmploc *savehandler; struct localvar *savelocalvars; setstackmark(&smark); result->fd = -1; result->buf = NULL; result->nleft = 0; result->jp = NULL; if (n == NULL) { exitstatus = 0; goto out; } exitstatus = oexitstatus; if (is_valid_fast_cmdsubst(n)) { savelocalvars = localvars; localvars = NULL; forcelocal++; savehandler = handler; if (setjmp(jmploc.loc)) { if (exception == EXERROR || exception == EXEXEC) exitstatus = 2; else if (exception != 0) { handler = savehandler; forcelocal--; poplocalvars(); localvars = savelocalvars; longjmp(handler->loc, 1); } } else { handler = &jmploc; evalcommand(n, EV_BACKCMD, result); } handler = savehandler; forcelocal--; poplocalvars(); localvars = savelocalvars; } else { if (pipe(pip) < 0) error("Pipe call failed: %s", strerror(errno)); jp = makejob(n, 1); if (forkshell(jp, n, FORK_NOJOB) == 0) { FORCEINTON; close(pip[0]); if (pip[1] != 1) { dup2(pip[1], 1); close(pip[1]); } evaltree(n, EV_EXIT); } close(pip[1]); result->fd = pip[0]; result->jp = jp; } out: popstackmark(&smark); TRACE(("evalbackcmd done: fd=%d buf=%p nleft=%d jp=%p\n", result->fd, result->buf, result->nleft, result->jp)); }
void evaltree(union node *n, int flags) { int do_etest; union node *next; struct stackmark smark; setstackmark(&smark); do_etest = 0; if (n == NULL) { TRACE(("evaltree(NULL) called\n")); exitstatus = 0; goto out; } do { next = NULL; #ifndef NO_HISTORY displayhist = 1; /* show history substitutions done with fc */ #endif TRACE(("evaltree(%p: %d) called\n", (void *)n, n->type)); switch (n->type) { case NSEMI: evaltree(n->nbinary.ch1, flags & ~EV_EXIT); if (evalskip) goto out; next = n->nbinary.ch2; break; case NAND: evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip || exitstatus != 0) { goto out; } next = n->nbinary.ch2; break; case NOR: evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip || exitstatus == 0) goto out; next = n->nbinary.ch2; break; case NREDIR: evalredir(n, flags); break; case NSUBSHELL: evalsubshell(n, flags); do_etest = !(flags & EV_TESTED); break; case NBACKGND: evalsubshell(n, flags); break; case NIF: { evaltree(n->nif.test, EV_TESTED); if (evalskip) goto out; if (exitstatus == 0) next = n->nif.ifpart; else if (n->nif.elsepart) next = n->nif.elsepart; else exitstatus = 0; break; } case NWHILE: case NUNTIL: evalloop(n, flags & ~EV_EXIT); break; case NFOR: evalfor(n, flags & ~EV_EXIT); break; case NCASE: next = evalcase(n); break; case NCLIST: next = n->nclist.body; break; case NCLISTFALLTHRU: if (n->nclist.body) { evaltree(n->nclist.body, flags & ~EV_EXIT); if (evalskip) goto out; } next = n->nclist.next; break; case NDEFUN: defun(n->narg.text, n->narg.next); exitstatus = 0; break; case NNOT: evaltree(n->nnot.com, EV_TESTED); if (evalskip) goto out; exitstatus = !exitstatus; break; case NPIPE: evalpipe(n); do_etest = !(flags & EV_TESTED); break; case NCMD: evalcommand(n, flags, (struct backcmd *)NULL); do_etest = !(flags & EV_TESTED); break; default: out1fmt("Node type = %d\n", n->type); flushout(&output); break; } n = next; popstackmark(&smark); setstackmark(&smark); } while (n != NULL); out: popstackmark(&smark); if (pendingsig) dotrap(); if (eflag && exitstatus != 0 && do_etest) exitshell(exitstatus); if (flags & EV_EXIT) exraise(EXEXIT); }