diff --git a/eval.c b/eval.c index 161891f..f10479a 100644 --- a/eval.c +++ b/eval.c @@ -1,8 +1,8 @@ -/* $OpenBSD: eval.c,v 1.33 2007/08/02 11:05:54 fgsch Exp $ */ +/* $OpenBSD: eval.c,v 1.34 2009/01/29 23:27:26 jaredy Exp $ */ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.52 2009/03/14 18:12:51 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.53 2009/03/22 17:47:35 tg Exp $"); #ifdef MKSH_SMALL #define MKSH_NOPWNAM @@ -1069,7 +1069,7 @@ comsub(Expand *xp, const char *cp) ksh_dup2(pv[1], 1, false); close(pv[1]); } - execute(t, XFORK|XXCOM|XPIPEO); + execute(t, XFORK|XXCOM|XPIPEO, NULL); restfd(1, ofd1); startlast(); xp->split = 1; /* waitlast() */ diff --git a/exec.c b/exec.c index f7a4f9b..c15a19d 100644 --- a/exec.c +++ b/exec.c @@ -1,11 +1,11 @@ -/* $OpenBSD: exec.c,v 1.48 2007/09/05 19:02:01 otto Exp $ */ +/* $OpenBSD: exec.c,v 1.49 2009/01/29 23:27:26 jaredy Exp $ */ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.50 2009/03/16 15:50:12 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.51 2009/03/22 17:47:36 tg Exp $"); static int comexec(struct op *, struct tbl *volatile, const char **, - int volatile); + int volatile, volatile int *); static void scriptexec(struct op *, const char **) __attribute__((noreturn)); static int call_builtin(struct tbl *, const char **); @@ -21,7 +21,8 @@ static void dbteste_error(Test_env *, int, const char *); */ int execute(struct op *volatile t, - volatile int flags) /* if XEXEC don't fork */ + volatile int flags, /* if XEXEC don't fork */ + volatile int *xerrok) { int i; volatile int rv = 0; @@ -36,7 +37,8 @@ execute(struct op *volatile t, return 0; if ((flags&XFORK) && !(flags&XEXEC) && t->type != TPIPE) - return exchild(t, flags & ~XTIME, -1); /* run in sub-process */ + /* run in sub-process */ + return exchild(t, flags & ~XTIME, xerrok, -1); newenv(E_EXEC); if (trap) @@ -95,11 +97,11 @@ execute(struct op *volatile t, switch (t->type) { case TCOM: - rv = comexec(t, tp, (const char **)ap, flags); + rv = comexec(t, tp, (const char **)ap, flags, xerrok); break; case TPAREN: - rv = execute(t->left, flags|XFORK); + rv = execute(t->left, flags | XFORK, xerrok); break; case TPIPE: @@ -115,7 +117,8 @@ execute(struct op *volatile t, * (: ; cat /etc/termcap) | sleep 1 * will hang forever). */ - exchild(t->left, flags|XPIPEO|XCCLOSE, pv[0]); + exchild(t->left, flags | XPIPEO | XCCLOSE, + NULL, pv[0]); ksh_dup2(pv[0], 0, false); /* stdin of next */ closepipe(pv); flags |= XPIPEI; @@ -124,17 +127,17 @@ execute(struct op *volatile t, restfd(1, e->savefd[1]); /* stdout of last */ e->savefd[1] = 0; /* no need to re-restore this */ /* Let exchild() close 0 in parent, after fork, before wait */ - i = exchild(t, flags|XPCLOSE, 0); + i = exchild(t, flags | XPCLOSE, xerrok, 0); if (!(flags&XBGND) && !(flags&XXCOM)) rv = i; break; case TLIST: while (t->type == TLIST) { - execute(t->left, flags & XERROK); + execute(t->left, flags & XERROK, NULL); t = t->right; } - rv = execute(t, flags & XERROK); + rv = execute(t, flags & XERROK, xerrok); break; case TCOPROC: @@ -191,8 +194,8 @@ execute(struct op *volatile t, * job is actually created. */ flags &= ~XEXEC; - exchild(t->left, flags|XBGND|XFORK|XCOPROC|XCCLOSE, - coproc.readw); + exchild(t->left, flags | XBGND | XFORK | XCOPROC | XCCLOSE, + NULL, coproc.readw); break; } @@ -201,20 +204,24 @@ execute(struct op *volatile t, * forks again for async... parent should optimise * this to "foo &"... */ - rv = execute(t->left, (flags&~XEXEC)|XBGND|XFORK); + rv = execute(t->left, (flags&~XEXEC)|XBGND|XFORK, xerrok); break; case TOR: case TAND: - rv = execute(t->left, XERROK); - if (t->right != NULL && (rv == 0) == (t->type == TAND)) - rv = execute(t->right, flags & XERROK); - else - flags |= XERROK; + rv = execute(t->left, XERROK, xerrok); + if ((rv == 0) == (t->type == TAND)) + rv = execute(t->right, XERROK, xerrok); + flags |= XERROK; + if (xerrok) + *xerrok = 1; break; case TBANG: - rv = !execute(t->right, XERROK); + rv = !execute(t->right, XERROK, xerrok); + flags |= XERROK; + if (xerrok) + *xerrok = 1; break; case TDBRACKET: @@ -257,7 +264,7 @@ execute(struct op *volatile t, if (t->type == TFOR) { while (*ap != NULL) { setstr(global(t->str), *ap++, KSH_UNWIND_ERROR); - rv = execute(t->left, flags & XERROK); + rv = execute(t->left, flags & XERROK, xerrok); } } else { /* TSELECT */ for (;;) { @@ -267,7 +274,7 @@ execute(struct op *volatile t, } is_first = false; setstr(global(t->str), cp, KSH_UNWIND_ERROR); - rv = execute(t->left, flags & XERROK); + rv = execute(t->left, flags & XERROK, xerrok); } } } @@ -290,17 +297,18 @@ execute(struct op *volatile t, } } rv = 0; /* in case of a continue */ - while ((execute(t->left, XERROK) == 0) == (t->type == TWHILE)) - rv = execute(t->right, flags & XERROK); + while ((execute(t->left, XERROK, NULL) == 0) == + (t->type == TWHILE)) + rv = execute(t->right, flags & XERROK, xerrok); break; case TIF: case TELIF: if (t->right == NULL) break; /* should be error */ - rv = execute(t->left, XERROK) == 0 ? - execute(t->right->left, flags & XERROK) : - execute(t->right->right, flags & XERROK); + rv = execute(t->left, XERROK, NULL) == 0 ? + execute(t->right->left, flags & XERROK, xerrok) : + execute(t->right->right, flags & XERROK, xerrok); break; case TCASE: @@ -312,11 +320,11 @@ execute(struct op *volatile t, goto Found; break; Found: - rv = execute(t->left, flags & XERROK); + rv = execute(t->left, flags & XERROK, xerrok); break; case TBRACE: - rv = execute(t->left, flags & XERROK); + rv = execute(t->left, flags & XERROK, xerrok); break; case TFUNCT: @@ -327,7 +335,7 @@ execute(struct op *volatile t, /* Clear XEXEC so nested execute() call doesn't exit * (allows "ls -l | time grep foo"). */ - rv = timex(t, flags & ~XEXEC); + rv = timex(t, flags & ~XEXEC, xerrok); break; case TEXEC: /* an eval'd TCOM */ @@ -353,7 +361,8 @@ execute(struct op *volatile t, quitenv(NULL); /* restores IO */ if ((flags&XEXEC)) unwind(LEXIT); /* exit child */ - if (rv != 0 && !(flags & XERROK)) { + if (rv != 0 && !(flags & XERROK) && + (xerrok == NULL || !*xerrok)) { trapsig(SIGERR_); if (Flag(FERREXIT)) unwind(LERROR); @@ -367,7 +376,7 @@ execute(struct op *volatile t, static int comexec(struct op *t, struct tbl *volatile tp, const char **ap, - volatile int flags) + volatile int flags, volatile int *xerrok) { int i; volatile int rv = 0; @@ -579,7 +588,7 @@ comexec(struct op *t, struct tbl *volatile tp, const char **ap, i = sigsetjmp(e->jbuf, 0); if (i == 0) { /* seems odd to pass XERROK here, but at&t ksh does */ - exstat = execute(tp->val.t, flags & XERROK); + exstat = execute(tp->val.t, flags & XERROK, xerrok); i = LRETURN; } kshname = old_kshname; @@ -652,7 +661,7 @@ comexec(struct op *t, struct tbl *volatile tp, const char **ap, texec.left = t; /* for tprint */ texec.str = tp->val.s; texec.args = ap; - rv = exchild(&texec, flags, -1); + rv = exchild(&texec, flags, xerrok, -1); break; } Leave: diff --git a/funcs.c b/funcs.c index 6c59b64..b9e9a94 100644 --- a/funcs.c +++ b/funcs.c @@ -1,11 +1,11 @@ /* $OpenBSD: c_ksh.c,v 1.31 2008/05/17 23:31:52 sobrado Exp $ */ -/* $OpenBSD: c_sh.c,v 1.38 2008/07/23 16:34:38 jaredy Exp $ */ +/* $OpenBSD: c_sh.c,v 1.39 2009/01/29 23:27:26 jaredy Exp $ */ /* $OpenBSD: c_test.c,v 1.17 2005/03/30 17:16:37 deraadt Exp $ */ /* $OpenBSD: c_ulimit.c,v 1.17 2008/03/21 12:51:19 millert Exp $ */ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.95 2009/03/15 16:13:39 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.96 2009/03/22 17:47:36 tg Exp $"); /* A leading = means assignments before command are kept; * a leading * means a POSIX special builtin; @@ -2196,7 +2196,7 @@ c_times(const char **wp __unused) * time pipeline (really a statement, not a built-in command) */ int -timex(struct op *t, int f) +timex(struct op *t, int f, volatile int *xerrok) { #define TF_NOARGS BIT(0) #define TF_NOREAL BIT(1) /* don't report real time */ @@ -2222,7 +2222,7 @@ timex(struct op *t, int f) */ timerclear(&j_usrtime); timerclear(&j_systime); - rv = execute(t->left, f | XTIME); + rv = execute(t->left, f | XTIME, xerrok); if (t->left->type == TCOM) tf |= t->left->str[0]; gettimeofday(&tv1, NULL); diff --git a/jobs.c b/jobs.c index 15c8b9e..b4b33c0 100644 --- a/jobs.c +++ b/jobs.c @@ -1,8 +1,8 @@ -/* $OpenBSD: jobs.c,v 1.36 2007/09/06 19:57:47 otto Exp $ */ +/* $OpenBSD: jobs.c,v 1.37 2009/01/29 23:27:26 jaredy Exp $ */ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.44 2009/02/23 16:17:44 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.45 2009/03/22 17:47:37 tg Exp $"); /* Order important! */ #define PRUNNING 0 @@ -289,7 +289,9 @@ j_change(void) /* execute tree in child subprocess */ int -exchild(struct op *t, int flags, /* used if XPCLOSE or XCCLOSE */ int close_fd) +exchild(struct op *t, int flags, + volatile int *xerrok, + /* used if XPCLOSE or XCCLOSE */ int close_fd) { static Proc *last_proc; /* for pipelines */ @@ -305,7 +307,7 @@ exchild(struct op *t, int flags, /* used if XPCLOSE or XCCLOSE */ int close_fd) /* Clear XFORK|XPCLOSE|XCCLOSE|XCOPROC|XPIPEO|XPIPEI|XXCOM|XBGND * (also done in another execute() below) */ - return execute(t, flags & (XEXEC | XERROK)); + return execute(t, flags & (XEXEC | XERROK), xerrok); /* no SIGCHLDs while messing with job and process lists */ sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); @@ -430,7 +432,8 @@ exchild(struct op *t, int flags, /* used if XPCLOSE or XCCLOSE */ int close_fd) Flag(FTALKING) = 0; tty_close(); cleartraps(); - execute(t, (flags & XERROK) | XEXEC); /* no return */ + /* no return */ + execute(t, (flags & XERROK) | XEXEC, NULL); #ifndef MKSH_SMALL if (t->type == TPIPE) unwind(LLEAVE); diff --git a/main.c b/main.c index 395c13a..bdfe56f 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.44 2008/07/05 07:25:18 djm Exp $ */ +/* $OpenBSD: main.c,v 1.45 2009/01/29 23:27:26 jaredy Exp $ */ /* $OpenBSD: tty.c,v 1.9 2006/03/14 22:08:01 deraadt Exp $ */ /* $OpenBSD: io.c,v 1.22 2006/03/17 16:30:13 millert Exp $ */ /* $OpenBSD: table.c,v 1.13 2009/01/17 22:06:44 millert Exp $ */ @@ -13,7 +13,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.121 2009/03/22 17:31:16 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.122 2009/03/22 17:47:37 tg Exp $"); extern char **environ; @@ -566,7 +566,7 @@ shell(Source * volatile s, volatile int toplevel) } } if (t && (!Flag(FNOEXEC) || (s->flags & SF_TTY))) - exstat = execute(t, 0); + exstat = execute(t, 0, NULL); if (t != NULL && t->type != TEOF && interactive && really_exit) really_exit = 0; diff --git a/sh.h b/sh.h index 006c967..422ee31 100644 --- a/sh.h +++ b/sh.h @@ -4,7 +4,7 @@ /* $OpenBSD: tree.h,v 1.10 2005/03/28 21:28:22 deraadt Exp $ */ /* $OpenBSD: expand.h,v 1.6 2005/03/30 17:16:37 deraadt Exp $ */ /* $OpenBSD: lex.h,v 1.11 2006/05/29 18:22:24 otto Exp $ */ -/* $OpenBSD: proto.h,v 1.31 2009/01/17 22:06:44 millert Exp $ */ +/* $OpenBSD: proto.h,v 1.32 2009/01/29 23:27:26 jaredy Exp $ */ /* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */ /* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */ @@ -102,7 +102,7 @@ #define __SCCSID(x) __IDSTRING(sccsid,x) #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.281 2009/03/22 17:31:17 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.282 2009/03/22 17:47:38 tg Exp $"); #endif #define MKSH_VERSION "R36 2009/03/17" @@ -1289,7 +1289,7 @@ char *debunk(char *, const char *, size_t); void expand(const char *, XPtrV *, int); int glob_str(char *, XPtrV *, int); /* exec.c */ -int execute(struct op * volatile, volatile int); +int execute(struct op * volatile, volatile int, volatile int *); int shcomexec(const char **); struct tbl *findfunc(const char *, unsigned int, int); int define(const char *, struct op *); @@ -1334,7 +1334,7 @@ int c_set(const char **); int c_unset(const char **); int c_ulimit(const char **); int c_times(const char **); -int timex(struct op *, int); +int timex(struct op *, int, volatile int *); void timex_hook(struct op *, char ** volatile *); int c_exec(const char **); int c_builtin(const char **); @@ -1383,7 +1383,7 @@ void setexecsig(Trap *, int); void j_init(int); void j_exit(void); void j_change(void); -int exchild(struct op *, int, int); +int exchild(struct op *, int, volatile int *, int); void startlast(void); int waitlast(void); int waitfor(const char *, int *);