diff options
Diffstat (limited to 'package/busybox/patches/903-ash.patch')
-rw-r--r-- | package/busybox/patches/903-ash.patch | 155 |
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; |