summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c72
1 files changed, 53 insertions, 19 deletions
diff --git a/shell/ash.c b/shell/ash.c
index dd20fe338..45b00709a 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1569,14 +1569,14 @@ static char *optionarg; /* set by nextopt (like getopt) */
1569static char *optptr; /* used by nextopt */ 1569static char *optptr; /* used by nextopt */
1570 1570
1571/* 1571/*
1572 * XXX - should get rid of. have all builtins use getopt(3). the 1572 * XXX - should get rid of. Have all builtins use getopt(3).
1573 * library getopt must have the BSD extension static variable "optreset" 1573 * The library getopt must have the BSD extension static variable
1574 * otherwise it can't be used within the shell safely. 1574 * "optreset", otherwise it can't be used within the shell safely.
1575 * 1575 *
1576 * Standard option processing (a la getopt) for builtin routines. The 1576 * Standard option processing (a la getopt) for builtin routines.
1577 * only argument that is passed to nextopt is the option string; the 1577 * The only argument that is passed to nextopt is the option string;
1578 * other arguments are unnecessary. It return the character, or '\0' on 1578 * the other arguments are unnecessary. It returns the character,
1579 * end of input. 1579 * or '\0' on end of input.
1580 */ 1580 */
1581static int 1581static int
1582nextopt(const char *optstring) 1582nextopt(const char *optstring)
@@ -1587,13 +1587,20 @@ nextopt(const char *optstring)
1587 1587
1588 p = optptr; 1588 p = optptr;
1589 if (p == NULL || *p == '\0') { 1589 if (p == NULL || *p == '\0') {
1590 /* We ate entire "-param", take next one */
1590 p = *argptr; 1591 p = *argptr;
1591 if (p == NULL || *p != '-' || *++p == '\0') 1592 if (p == NULL)
1593 return '\0';
1594 if (*p != '-')
1595 return '\0';
1596 if (*++p == '\0') /* just "-" ? */
1592 return '\0'; 1597 return '\0';
1593 argptr++; 1598 argptr++;
1594 if (LONE_DASH(p)) /* check for "--" */ 1599 if (LONE_DASH(p)) /* "--" ? */
1595 return '\0'; 1600 return '\0';
1601 /* p => next "-param" */
1596 } 1602 }
1603 /* p => some option char in the middle of a "-param" */
1597 c = *p++; 1604 c = *p++;
1598 for (q = optstring; *q != c;) { 1605 for (q = optstring; *q != c;) {
1599 if (*q == '\0') 1606 if (*q == '\0')
@@ -1602,8 +1609,11 @@ nextopt(const char *optstring)
1602 q++; 1609 q++;
1603 } 1610 }
1604 if (*++q == ':') { 1611 if (*++q == ':') {
1605 if (*p == '\0' && (p = *argptr++) == NULL) 1612 if (*p == '\0') {
1606 ash_msg_and_raise_error("no arg for -%c option", c); 1613 p = *argptr++;
1614 if (p == NULL)
1615 ash_msg_and_raise_error("no arg for -%c option", c);
1616 }
1607 optionarg = p; 1617 optionarg = p;
1608 p = NULL; 1618 p = NULL;
1609 } 1619 }
@@ -7428,8 +7438,10 @@ commandcmd(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
7428 else if (c != 'p') 7438 else if (c != 'p')
7429 abort(); 7439 abort();
7430#endif 7440#endif
7431 if (verify) 7441 /* Mimic bash: just "command -v" doesn't complain, it's a nop */
7442 if (verify && (*argptr != NULL)) {
7432 return describe_command(*argptr, verify - VERIFY_BRIEF); 7443 return describe_command(*argptr, verify - VERIFY_BRIEF);
7444 }
7433 7445
7434 return 0; 7446 return 0;
7435} 7447}
@@ -7788,16 +7800,33 @@ static void prehash(union node *);
7788static void 7800static void
7789evaltree(union node *n, int flags) 7801evaltree(union node *n, int flags)
7790{ 7802{
7803
7804 struct jmploc *volatile savehandler = exception_handler;
7805 struct jmploc jmploc;
7791 int checkexit = 0; 7806 int checkexit = 0;
7792 void (*evalfn)(union node *, int); 7807 void (*evalfn)(union node *, int);
7793 unsigned isor;
7794 int status; 7808 int status;
7809
7795 if (n == NULL) { 7810 if (n == NULL) {
7796 TRACE(("evaltree(NULL) called\n")); 7811 TRACE(("evaltree(NULL) called\n"));
7797 goto out; 7812 goto out1;
7798 } 7813 }
7799 TRACE(("pid %d, evaltree(%p: %d, %d) called\n", 7814 TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
7800 getpid(), n, n->type, flags)); 7815 getpid(), n, n->type, flags));
7816
7817 exception_handler = &jmploc;
7818 {
7819 int err = setjmp(jmploc.loc);
7820 if (err) {
7821 /* if it was a signal, check for trap handlers */
7822 if (exception == EXSIG)
7823 goto out;
7824 /* continue on the way out */
7825 exception_handler = savehandler;
7826 longjmp(exception_handler->loc, err);
7827 }
7828 }
7829
7801 switch (n->type) { 7830 switch (n->type) {
7802 default: 7831 default:
7803#if DEBUG 7832#if DEBUG
@@ -7843,19 +7872,20 @@ evaltree(union node *n, int flags)
7843 goto calleval; 7872 goto calleval;
7844 case NAND: 7873 case NAND:
7845 case NOR: 7874 case NOR:
7846 case NSEMI: 7875 case NSEMI: {
7876
7847#if NAND + 1 != NOR 7877#if NAND + 1 != NOR
7848#error NAND + 1 != NOR 7878#error NAND + 1 != NOR
7849#endif 7879#endif
7850#if NOR + 1 != NSEMI 7880#if NOR + 1 != NSEMI
7851#error NOR + 1 != NSEMI 7881#error NOR + 1 != NSEMI
7852#endif 7882#endif
7853 isor = n->type - NAND; 7883 unsigned is_or = n->type - NAND;
7854 evaltree( 7884 evaltree(
7855 n->nbinary.ch1, 7885 n->nbinary.ch1,
7856 (flags | ((isor >> 1) - 1)) & EV_TESTED 7886 (flags | ((is_or >> 1) - 1)) & EV_TESTED
7857 ); 7887 );
7858 if (!exitstatus == isor) 7888 if (!exitstatus == is_or)
7859 break; 7889 break;
7860 if (!evalskip) { 7890 if (!evalskip) {
7861 n = n->nbinary.ch2; 7891 n = n->nbinary.ch2;
@@ -7866,6 +7896,7 @@ evaltree(union node *n, int flags)
7866 break; 7896 break;
7867 } 7897 }
7868 break; 7898 break;
7899 }
7869 case NIF: 7900 case NIF:
7870 evaltree(n->nif.test, EV_TESTED); 7901 evaltree(n->nif.test, EV_TESTED);
7871 if (evalskip) 7902 if (evalskip)
@@ -7886,8 +7917,11 @@ evaltree(union node *n, int flags)
7886 exitstatus = status; 7917 exitstatus = status;
7887 break; 7918 break;
7888 } 7919 }
7920
7889 out: 7921 out:
7890 if ((checkexit & exitstatus)) 7922 exception_handler = savehandler;
7923 out1:
7924 if (checkexit & exitstatus)
7891 evalskip |= SKIPEVAL; 7925 evalskip |= SKIPEVAL;
7892 else if (pendingsig && dotrap()) 7926 else if (pendingsig && dotrap())
7893 goto exexit; 7927 goto exexit;