X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/24ef8cad2598c8dc0026e4124569498520eff67b..f15f366852663832eb02933efecc062dbff4bc59:/bin/sh/eval.c diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 703d4c2c85..ecc53f4c46 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)eval.c 8.9 (Berkeley) 6/8/95 - * $FreeBSD: src/bin/sh/eval.c,v 1.101 2011/02/05 14:08:51 jilles Exp $ + * $FreeBSD: src/bin/sh/eval.c,v 1.110 2011/06/16 21:50:28 jilles Exp $ */ #include @@ -141,7 +141,7 @@ evalcmd(int argc, char **argv) STPUTC('\0', concat); p = grabstackstr(concat); } - evalstring(p, builtin_flags & EV_TESTED); + evalstring(p, builtin_flags); } else exitstatus = 0; return exitstatus; @@ -166,7 +166,7 @@ evalstring(char *s, int flags) setstackmark(&smark); setinputstring(s, 1); while ((n = parsecmd(0)) != NEOF) { - if (n != NULL) { + if (n != NULL && !nflag) { if (flags_exit && preadateof()) evaltree(n, flags | EV_EXIT); else @@ -180,7 +180,7 @@ evalstring(char *s, int flags) if (!any) exitstatus = 0; if (flags_exit) - exitshell(exitstatus); + exraise(EXEXIT); } @@ -286,8 +286,10 @@ evaltree(union node *n, int flags) out: if (pendingsigs) dotrap(); - if ((flags & EV_EXIT) || (eflag && exitstatus != 0 && do_etest)) + if (eflag && exitstatus != 0 && do_etest) exitshell(exitstatus); + if (flags & EV_EXIT) + exraise(EXEXIT); } @@ -408,6 +410,7 @@ evalsubshell(union node *n, int flags) struct job *jp; int backgnd = (n->type == NBACKGND); + oexitstatus = exitstatus; expredir(n->nredir.redirect); if ((!backgnd && flags & EV_EXIT && !have_traps()) || forkshell(jp = makejob(n, 1), n, backgnd) == 0) { @@ -419,7 +422,8 @@ evalsubshell(union node *n, int flags) INTOFF; exitstatus = waitforjob(jp, NULL); INTON; - } + } else + exitstatus = 0; } @@ -434,6 +438,7 @@ evalredir(union node *n, int flags) struct jmploc *savehandler; volatile int in_redirect = 1; + oexitstatus = exitstatus; expredir(n->nredir.redirect); savehandler = handler; if (setjmp(jmploc.loc)) { @@ -441,8 +446,8 @@ evalredir(union node *n, int flags) handler = savehandler; e = exception; + popredir(); if (e == EXERROR || e == EXEXEC) { - popredir(); if (in_redirect) { exitstatus = 2; return; @@ -476,7 +481,6 @@ expredir(union node *n) for (redir = n ; redir ; redir = redir->nfile.next) { struct arglist fn; fn.lastp = &fn.list; - oexitstatus = exitstatus; switch (redir->type) { case NFROM: case NTO: @@ -551,7 +555,8 @@ evalpipe(union node *n) if (prevfd >= 0) close(prevfd); prevfd = pip[0]; - close(pip[1]); + if (pip[1] != -1) + close(pip[1]); } INTON; if (n->npipe.backgnd == 0) { @@ -559,7 +564,8 @@ evalpipe(union node *n) exitstatus = waitforjob(jp, NULL); TRACE(("evalpipe: job done exit status %d\n", exitstatus)); INTON; - } + } else + exitstatus = 0; } @@ -567,14 +573,8 @@ evalpipe(union node *n) static int is_valid_fast_cmdsubst(union node *n) { - union node *argp; - if (n->type != NCMD) - return 0; - for (argp = n->ncmd.args ; argp ; argp = argp->narg.next) - if (expandhassideeffects(argp->narg.text)) - return 0; - return 1; + return (n->type == NCMD); } /* @@ -592,6 +592,7 @@ evalbackcmd(union node *n, struct backcmd *result) struct stackmark smark; /* unnecessary */ struct jmploc jmploc; struct jmploc *savehandler; + struct localvar *savelocalvars; setstackmark(&smark); result->fd = -1; @@ -604,12 +605,18 @@ evalbackcmd(union node *n, struct backcmd *result) } if (is_valid_fast_cmdsubst(n)) { exitstatus = oexitstatus; + 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 { @@ -617,6 +624,9 @@ evalbackcmd(union node *n, struct backcmd *result) evalcommand(n, EV_BACKCMD, result); } handler = savehandler; + forcelocal--; + poplocalvars(); + localvars = savelocalvars; } else { exitstatus = 0; if (pipe(pip) < 0) @@ -712,15 +722,9 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd) oexitstatus = exitstatus; exitstatus = 0; for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { - char *p = argp->narg.text; - if (varflag && is_name(*p)) { - do { - p++; - } while (is_in_name(*p)); - if (*p == '=') { - expandarg(argp, &varlist, EXP_VARTILDE); - continue; - } + if (varflag && isassignment(argp->narg.text)) { + expandarg(argp, &varlist, EXP_VARTILDE); + continue; } expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); varflag = 0; @@ -748,8 +752,9 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd) /* Print the command if xflag is set. */ if (xflag) { char sep = 0; - const char *p; - out2str(ps4val()); + const char *p, *ps4; + ps4 = expandstr(ps4val()); + out2str(ps4 != NULL ? ps4 : ps4val()); for (sp = varlist.list ; sp ; sp = sp->next) { if (sep != 0) out2c(' '); @@ -906,6 +911,7 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd) dup2(pip[1], 1); close(pip[1]); } + flags &= ~EV_BACKCMD; } flags |= EV_EXIT; } @@ -930,8 +936,7 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd) if (setjmp(jmploc.loc)) { freeparam(&shellparam); shellparam = saveparam; - if (exception == EXERROR || exception == EXEXEC) - popredir(); + popredir(); unreffunc(cmdentry.u.func); poplocalvars(); localvars = savelocalvars; @@ -946,10 +951,8 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd) for (sp = varlist.list ; sp ; sp = sp->next) mklocal(sp->text); exitstatus = oexitstatus; - if (flags & EV_TESTED) - evaltree(getfuncnode(cmdentry.u.func), EV_TESTED); - else - evaltree(getfuncnode(cmdentry.u.func), 0); + evaltree(getfuncnode(cmdentry.u.func), + flags & (EV_TESTED | EV_EXIT)); INTOFF; unreffunc(cmdentry.u.func); poplocalvars(); @@ -985,7 +988,10 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd) savehandler = handler; if (setjmp(jmploc.loc)) { e = exception; - exitstatus = (e == EXINT)? SIGINT+128 : 2; + if (e == EXINT) + exitstatus = SIGINT+128; + else if (e != EXEXIT) + exitstatus = 2; goto cmddone; } handler = &jmploc; @@ -1021,8 +1027,7 @@ cmddone: backcmd->nleft = memout.nextc - memout.buf; memout.buf = NULL; } - if (cmdentry.u.index != EXECCMD && - (e == -1 || e == EXERROR || e == EXEXEC)) + if (cmdentry.u.index != EXECCMD) popredir(); if (e != -1) { if ((e != EXERROR && e != EXEXEC) @@ -1058,7 +1063,8 @@ parent: /* parent process gets here (if we forked) */ backcmd->fd = pip[0]; close(pip[1]); backcmd->jp = jp; - } + } else + exitstatus = 0; out: if (lastarg)