summaryrefslogtreecommitdiffstats
path: root/system/pdksh/patches/111_mksh-set-e.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/pdksh/patches/111_mksh-set-e.patch')
-rw-r--r--system/pdksh/patches/111_mksh-set-e.patch422
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
++---
++