diff options
Diffstat (limited to 'system/pdksh/patches/111_mksh-set-e.patch')
-rw-r--r-- | system/pdksh/patches/111_mksh-set-e.patch | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/system/pdksh/patches/111_mksh-set-e.patch b/system/pdksh/patches/111_mksh-set-e.patch new file mode 100644 index 0000000000..ca6f42b18f --- /dev/null +++ b/system/pdksh/patches/111_mksh-set-e.patch @@ -0,0 +1,422 @@ +Fix `set -e' handling from mksh (see bugs #71256, #546332, closes: #387755). +Index: pdksh-5.2.14/exec.c +=================================================================== +--- pdksh-5.2.14.orig/exec.c 2009-09-19 11:54:58.000000000 +0200 ++++ pdksh-5.2.14/exec.c 2009-09-19 11:55:01.000000000 +0200 +@@ -15,7 +15,7 @@ + #endif /* KSH */ + + static int comexec ARGS((struct op *t, struct tbl *volatile tp, char **ap, +- int volatile flags)); ++ int volatile flags, volatile int * volatile xerrok)); + static void scriptexec ARGS((struct op *tp, char **ap)); + static int call_builtin ARGS((struct tbl *tp, char **wp)); + static int iosetup ARGS((struct ioword *iop, struct tbl *tp)); +@@ -70,12 +70,13 @@ + * execute command tree + */ + int +-execute(t, flags) ++execute(t, flags, xerrok) + struct op * volatile t; + volatile int flags; /* if XEXEC don't fork */ ++ volatile int * volatile xerrok; + { + int i; +- volatile int rv = 0; ++ volatile int rv = 0, dummy = 0; + int pv[2]; + char ** volatile ap; + char *s, *cp; +@@ -85,6 +86,10 @@ + if (t == NULL) + return 0; + ++ /* Caller doesn't care if XERROK should propagate. */ ++ if (xerrok == NULL) ++ xerrok = &dummy; ++ + /* Is this the end of a pipeline? If so, we want to evaluate the + * command arguments + bool_t eval_done = FALSE; +@@ -94,7 +99,7 @@ + } + */ + if ((flags&XFORK) && !(flags&XEXEC) && t->type != TPIPE) +- return exchild(t, flags & ~XTIME, -1); /* run in sub-process */ ++ return exchild(t, flags & ~XTIME, xerrok, -1); /* run in sub-process */ + + newenv(E_EXEC); + if (trap) +@@ -152,11 +157,11 @@ + + switch(t->type) { + case TCOM: +- rv = comexec(t, tp, ap, flags); ++ rv = comexec(t, tp, ap, flags, xerrok); + break; + + case TPAREN: +- rv = execute(t->left, flags|XFORK); ++ rv = execute(t->left, flags|XFORK, xerrok); + break; + + case TPIPE: +@@ -173,7 +178,7 @@ + * (: ; 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]); + (void) ksh_dup2(pv[0], 0, FALSE); /* stdin of next */ + closepipe(pv); + flags |= XPIPEI; +@@ -182,17 +187,17 @@ + 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; + + #ifdef KSH +@@ -257,7 +262,7 @@ + */ + flags &= ~XEXEC; + exchild(t->left, flags|XBGND|XFORK|XCOPROC|XCCLOSE, +- coproc.readw); ++ NULL, coproc.readw); + break; + } + #endif /* KSH */ +@@ -267,20 +272,24 @@ + * forks again for async... parent should optimize + * 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; + + #ifdef KSH +@@ -328,7 +337,7 @@ + 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); + } + } + #ifdef KSH +@@ -340,7 +349,7 @@ + } + is_first = FALSE; + setstr(global(t->str), cp, KSH_UNWIND_ERROR); +- rv = execute(t->left, flags & XERROK); ++ rv = execute(t->left, flags & XERROK, xerrok); + } + } + } +@@ -365,17 +374,17 @@ + } + } + 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: +@@ -387,11 +396,11 @@ + 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: +@@ -402,7 +411,7 @@ + /* 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 */ +@@ -430,7 +439,8 @@ + quitenv(); /* restores IO */ + if ((flags&XEXEC)) + unwind(LEXIT); /* exit child */ +- if (rv != 0 && !(flags & XERROK)) { ++ if (rv != 0 && !(flags & XERROK) ++ && (xerrok == NULL || !*xerrok)) { + if (Flag(FERREXIT)) + unwind(LERROR); + trapsig(SIGERR_); +@@ -443,11 +453,12 @@ + */ + + static int +-comexec(t, tp, ap, flags) ++comexec(t, tp, ap, flags, xerrok) + struct op *t; + struct tbl *volatile tp; + register char **ap; + int volatile flags; ++ volatile int * volatile xerrok; + { + int i; + volatile int rv = 0; +@@ -660,7 +671,7 @@ + i = ksh_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; +@@ -737,7 +748,7 @@ + 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: +Index: pdksh-5.2.14/c_sh.c +=================================================================== +--- pdksh-5.2.14.orig/c_sh.c 2009-09-19 11:54:58.000000000 +0200 ++++ pdksh-5.2.14/c_sh.c 2009-09-19 11:55:01.000000000 +0200 +@@ -725,9 +725,10 @@ + * time pipeline (really a statement, not a built-in command) + */ + int +-timex(t, f) ++timex(t, f, xerrok) + struct op *t; + int f; ++ volatile int * xerrok; + { + #define TF_NOARGS BIT(0) + #define TF_NOREAL BIT(1) /* don't report real time */ +@@ -753,7 +754,7 @@ + if (t->left->type == TCOM) + t->left->str = opts; + opts[0] = 0; +- rv = execute(t->left, f | XTIME); ++ rv = execute(t->left, f | XTIME, xerrok); + tf |= opts[0]; + t1t = ksh_times(&t1); + } else +Index: pdksh-5.2.14/eval.c +=================================================================== +--- pdksh-5.2.14.orig/eval.c 2009-09-19 11:54:58.000000000 +0200 ++++ pdksh-5.2.14/eval.c 2009-09-19 11:55:01.000000000 +0200 +@@ -877,7 +877,7 @@ + close(pv[1]); + } + +- execute(t, XFORK|XXCOM|XPIPEO); ++ execute(t, XFORK|XXCOM|XPIPEO, NULL); + restfd(1, ofd1); + startlast(); + xp->split = 1; /* waitlast() */ +Index: pdksh-5.2.14/jobs.c +=================================================================== +--- pdksh-5.2.14.orig/jobs.c 2009-09-19 11:54:58.000000000 +0200 ++++ pdksh-5.2.14/jobs.c 2009-09-19 11:55:01.000000000 +0200 +@@ -443,9 +443,10 @@ + + /* execute tree in child subprocess */ + int +-exchild(t, flags, close_fd) ++exchild(t, flags, xerrok, close_fd) + struct op *t; + int flags; ++ volatile int *xerrok; + int close_fd; /* used if XPCLOSE or XCCLOSE */ + { + static Proc *last_proc; /* for pipelines */ +@@ -464,7 +465,7 @@ + /* 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); + + #ifdef JOB_SIGS + /* no SIGCHLD's while messing with job and process lists */ +@@ -659,7 +660,7 @@ + #endif /* OS2 */ + tty_close(); + cleartraps(); +- execute(t, (flags & XERROK) | XEXEC); /* no return */ ++ execute(t, (flags & XERROK) | XEXEC, xerrok); /* no return */ + internal_errorf(0, "exchild: execute() returned"); + unwind(LLEAVE); + /* NOTREACHED */ +Index: pdksh-5.2.14/main.c +=================================================================== +--- pdksh-5.2.14.orig/main.c 2009-09-19 11:54:58.000000000 +0200 ++++ pdksh-5.2.14/main.c 2009-09-19 11:55:01.000000000 +0200 +@@ -634,7 +634,7 @@ + } + + 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; +Index: pdksh-5.2.14/proto.h +=================================================================== +--- pdksh-5.2.14.orig/proto.h 2009-09-19 11:54:58.000000000 +0200 ++++ pdksh-5.2.14/proto.h 2009-09-19 11:55:01.000000000 +0200 +@@ -42,7 +42,7 @@ + int c_unset ARGS((char **wp)); + int c_ulimit ARGS((char **wp)); + int c_times ARGS((char **wp)); +-int timex ARGS((struct op *t, int f)); ++int timex ARGS((struct op *t, int f, volatile int *xerrok)); + void timex_hook ARGS((struct op *t, char ** volatile *app)); + int c_exec ARGS((char **wp)); + int c_builtin ARGS((char **wp)); +@@ -65,7 +65,7 @@ + int glob_str ARGS((char *cp, XPtrV *wp, int markdirs)); + /* exec.c */ + int fd_clexec ARGS((int fd)); +-int execute ARGS((struct op * volatile t, volatile int flags)); ++int execute ARGS((struct op * volatile t, volatile int flags, volatile int * volatile xerrok)); + int shcomexec ARGS((char **wp)); + struct tbl * findfunc ARGS((const char *name, unsigned int h, int create)); + int define ARGS((const char *name, struct op *t)); +@@ -138,7 +138,7 @@ + void j_init ARGS((int mflagset)); + void j_exit ARGS((void)); + void j_change ARGS((void)); +-int exchild ARGS((struct op *t, int flags, int close_fd)); ++int exchild ARGS((struct op *t, int flags, volatile int * xerrok, int close_fd)); + void startlast ARGS((void)); + int waitlast ARGS((void)); + int waitfor ARGS((const char *cp, int *sigp)); +Index: pdksh-5.2.14/tests/debian-111.t +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ pdksh-5.2.14/tests/debian-111.t 2009-09-19 12:02:51.000000000 +0200 +@@ -0,0 +1,60 @@ ++name: debian-111-1 ++description: ++ Check set -e regression ++stdin: ++ set -e; true; false && true; echo OK ++expected-stdout: ++ OK ++--- ++name: debian-111-2 ++description: ++ Regression for #387755 ++stdin: ++ set -e ++ ! true ++ ! false ++ echo OK ++expected-stdout: ++ OK ++--- ++name: debian-111-3 ++description: ++ Regression for #387755 ++stdin: ++ set -e; (false); echo here ++expected-stdout: ++expected-fail: yes ++--- ++name: debian-111-4 ++description: ++ Regression for #387755 ++stdin: ++ set +e; (false); echo here ++expected-stdout: ++ here ++--- ++name: debian-111-5 ++description: ++ Regression for #71256 ++stdin: ++ set -e ++ if true; then ++ false && echo something ++ fi ++ echo OK ++expected-stdout: ++ OK ++--- ++name: debian-111-6 ++description: ++ Regression for #71256 ++stdin: ++ set +e ++ if true; then ++ false && echo something ++ fi ++ echo OK ++expected-stdout: ++ OK ++--- ++ |