summaryrefslogtreecommitdiff
path: root/package/busybox/patches/903-ash.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/busybox/patches/903-ash.patch')
-rw-r--r--package/busybox/patches/903-ash.patch155
1 files changed, 155 insertions, 0 deletions
diff --git a/package/busybox/patches/903-ash.patch b/package/busybox/patches/903-ash.patch
new file mode 100644
index 0000000000..efc1bc3439
--- /dev/null
+++ b/package/busybox/patches/903-ash.patch
@@ -0,0 +1,155 @@
+--- a/shell/ash.c
++++ b/shell/ash.c
+@@ -1569,14 +1569,14 @@
+ static char *optptr; /* used by nextopt */
+
+ /*
+- * XXX - should get rid of. have all builtins use getopt(3). the
+- * library getopt must have the BSD extension static variable "optreset"
+- * otherwise it can't be used within the shell safely.
++ * XXX - should get rid of. Have all builtins use getopt(3).
++ * The library getopt must have the BSD extension static variable
++ * "optreset", otherwise it can't be used within the shell safely.
+ *
+- * Standard option processing (a la getopt) for builtin routines. The
+- * only argument that is passed to nextopt is the option string; the
+- * other arguments are unnecessary. It return the character, or '\0' on
+- * end of input.
++ * Standard option processing (a la getopt) for builtin routines.
++ * The only argument that is passed to nextopt is the option string;
++ * the other arguments are unnecessary. It returns the character,
++ * or '\0' on end of input.
+ */
+ static int
+ nextopt(const char *optstring)
+@@ -1587,13 +1587,20 @@
+
+ p = optptr;
+ if (p == NULL || *p == '\0') {
++ /* We ate entire "-param", take next one */
+ p = *argptr;
+- if (p == NULL || *p != '-' || *++p == '\0')
++ if (p == NULL)
++ return '\0';
++ if (*p != '-')
++ return '\0';
++ if (*++p == '\0') /* just "-" ? */
+ return '\0';
+ argptr++;
+- if (LONE_DASH(p)) /* check for "--" */
++ if (LONE_DASH(p)) /* "--" ? */
+ return '\0';
++ /* p => next "-param" */
+ }
++ /* p => some option char in the middle of a "-param" */
+ c = *p++;
+ for (q = optstring; *q != c;) {
+ if (*q == '\0')
+@@ -1602,8 +1609,11 @@
+ q++;
+ }
+ if (*++q == ':') {
+- if (*p == '\0' && (p = *argptr++) == NULL)
+- ash_msg_and_raise_error("no arg for -%c option", c);
++ if (*p == '\0') {
++ p = *argptr++;
++ if (p == NULL)
++ ash_msg_and_raise_error("no arg for -%c option", c);
++ }
+ optionarg = p;
+ p = NULL;
+ }
+@@ -7428,8 +7438,10 @@
+ else if (c != 'p')
+ abort();
+ #endif
+- if (verify)
++ /* Mimic bash: just "command -v" doesn't complain, it's a nop */
++ if (verify && (*argptr != NULL)) {
+ return describe_command(*argptr, verify - VERIFY_BRIEF);
++ }
+
+ return 0;
+ }
+@@ -7788,16 +7800,33 @@
+ static void
+ evaltree(union node *n, int flags)
+ {
++
++ struct jmploc *volatile savehandler = exception_handler;
++ struct jmploc jmploc;
+ int checkexit = 0;
+ void (*evalfn)(union node *, int);
+- unsigned isor;
+ int status;
++
+ if (n == NULL) {
+ TRACE(("evaltree(NULL) called\n"));
+- goto out;
++ goto out1;
+ }
+ TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
+ getpid(), n, n->type, flags));
++
++ exception_handler = &jmploc;
++ {
++ int err = setjmp(jmploc.loc);
++ if (err) {
++ /* if it was a signal, check for trap handlers */
++ if (exception == EXSIG)
++ goto out;
++ /* continue on the way out */
++ exception_handler = savehandler;
++ longjmp(exception_handler->loc, err);
++ }
++ }
++
+ switch (n->type) {
+ default:
+ #if DEBUG
+@@ -7843,19 +7872,20 @@
+ goto calleval;
+ case NAND:
+ case NOR:
+- case NSEMI:
++ case NSEMI: {
++
+ #if NAND + 1 != NOR
+ #error NAND + 1 != NOR
+ #endif
+ #if NOR + 1 != NSEMI
+ #error NOR + 1 != NSEMI
+ #endif
+- isor = n->type - NAND;
++ unsigned is_or = n->type - NAND;
+ evaltree(
+ n->nbinary.ch1,
+- (flags | ((isor >> 1) - 1)) & EV_TESTED
++ (flags | ((is_or >> 1) - 1)) & EV_TESTED
+ );
+- if (!exitstatus == isor)
++ if (!exitstatus == is_or)
+ break;
+ if (!evalskip) {
+ n = n->nbinary.ch2;
+@@ -7866,6 +7896,7 @@
+ break;
+ }
+ break;
++ }
+ case NIF:
+ evaltree(n->nif.test, EV_TESTED);
+ if (evalskip)
+@@ -7886,8 +7917,11 @@
+ exitstatus = status;
+ break;
+ }
++
+ out:
+- if ((checkexit & exitstatus))
++ exception_handler = savehandler;
++ out1:
++ if (checkexit & exitstatus)
+ evalskip |= SKIPEVAL;
+ else if (pendingsig && dotrap())
+ goto exexit;