diff options
-rw-r--r-- | shell/ash.c | 136 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/exitcode1.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/exitcode1.tests | 2 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/exitcode1.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/exitcode1.tests | 2 |
5 files changed, 89 insertions, 55 deletions
diff --git a/shell/ash.c b/shell/ash.c index a113ff155..ec006af7d 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -5864,7 +5864,7 @@ struct backcmd { /* result of evalbackcmd */ | |||
5864 | /* These forward decls are needed to use "eval" code for backticks handling: */ | 5864 | /* These forward decls are needed to use "eval" code for backticks handling: */ |
5865 | static uint8_t back_exitstatus; /* exit status of backquoted command */ | 5865 | static uint8_t back_exitstatus; /* exit status of backquoted command */ |
5866 | #define EV_EXIT 01 /* exit after evaluating tree */ | 5866 | #define EV_EXIT 01 /* exit after evaluating tree */ |
5867 | static void evaltree(union node *, int); | 5867 | static int evaltree(union node *, int); |
5868 | 5868 | ||
5869 | static void FAST_FUNC | 5869 | static void FAST_FUNC |
5870 | evalbackcmd(union node *n, struct backcmd *result) | 5870 | evalbackcmd(union node *n, struct backcmd *result) |
@@ -8412,13 +8412,13 @@ dotrap(void) | |||
8412 | } | 8412 | } |
8413 | 8413 | ||
8414 | /* forward declarations - evaluation is fairly recursive business... */ | 8414 | /* forward declarations - evaluation is fairly recursive business... */ |
8415 | static void evalloop(union node *, int); | 8415 | static int evalloop(union node *, int); |
8416 | static void evalfor(union node *, int); | 8416 | static int evalfor(union node *, int); |
8417 | static void evalcase(union node *, int); | 8417 | static int evalcase(union node *, int); |
8418 | static void evalsubshell(union node *, int); | 8418 | static int evalsubshell(union node *, int); |
8419 | static void expredir(union node *); | 8419 | static void expredir(union node *); |
8420 | static void evalpipe(union node *, int); | 8420 | static int evalpipe(union node *, int); |
8421 | static void evalcommand(union node *, int); | 8421 | static int evalcommand(union node *, int); |
8422 | static int evalbltin(const struct builtincmd *, int, char **); | 8422 | static int evalbltin(const struct builtincmd *, int, char **); |
8423 | static void prehash(union node *); | 8423 | static void prehash(union node *); |
8424 | 8424 | ||
@@ -8426,14 +8426,14 @@ static void prehash(union node *); | |||
8426 | * Evaluate a parse tree. The value is left in the global variable | 8426 | * Evaluate a parse tree. The value is left in the global variable |
8427 | * exitstatus. | 8427 | * exitstatus. |
8428 | */ | 8428 | */ |
8429 | static void | 8429 | static int |
8430 | evaltree(union node *n, int flags) | 8430 | evaltree(union node *n, int flags) |
8431 | { | 8431 | { |
8432 | struct jmploc *volatile savehandler = exception_handler; | 8432 | struct jmploc *volatile savehandler = exception_handler; |
8433 | struct jmploc jmploc; | 8433 | struct jmploc jmploc; |
8434 | int checkexit = 0; | 8434 | int checkexit = 0; |
8435 | void (*evalfn)(union node *, int); | 8435 | int (*evalfn)(union node *, int); |
8436 | int status; | 8436 | int status = 0; |
8437 | int int_level; | 8437 | int int_level; |
8438 | 8438 | ||
8439 | SAVE_INT(int_level); | 8439 | SAVE_INT(int_level); |
@@ -8470,15 +8470,13 @@ evaltree(union node *n, int flags) | |||
8470 | break; | 8470 | break; |
8471 | #endif | 8471 | #endif |
8472 | case NNOT: | 8472 | case NNOT: |
8473 | evaltree(n->nnot.com, EV_TESTED); | 8473 | status = !evaltree(n->nnot.com, EV_TESTED); |
8474 | status = !exitstatus; | ||
8475 | goto setstatus; | 8474 | goto setstatus; |
8476 | case NREDIR: | 8475 | case NREDIR: |
8477 | expredir(n->nredir.redirect); | 8476 | expredir(n->nredir.redirect); |
8478 | status = redirectsafe(n->nredir.redirect, REDIR_PUSH); | 8477 | status = redirectsafe(n->nredir.redirect, REDIR_PUSH); |
8479 | if (!status) { | 8478 | if (!status) { |
8480 | evaltree(n->nredir.n, flags & EV_TESTED); | 8479 | status = evaltree(n->nredir.n, flags & EV_TESTED); |
8481 | status = exitstatus; | ||
8482 | } | 8480 | } |
8483 | popredir(/*drop:*/ 0, /*restore:*/ 0 /* not sure */); | 8481 | popredir(/*drop:*/ 0, /*restore:*/ 0 /* not sure */); |
8484 | goto setstatus; | 8482 | goto setstatus; |
@@ -8518,27 +8516,24 @@ evaltree(union node *n, int flags) | |||
8518 | #error NOR + 1 != NSEMI | 8516 | #error NOR + 1 != NSEMI |
8519 | #endif | 8517 | #endif |
8520 | unsigned is_or = n->type - NAND; | 8518 | unsigned is_or = n->type - NAND; |
8521 | evaltree( | 8519 | status = evaltree( |
8522 | n->nbinary.ch1, | 8520 | n->nbinary.ch1, |
8523 | (flags | ((is_or >> 1) - 1)) & EV_TESTED | 8521 | (flags | ((is_or >> 1) - 1)) & EV_TESTED |
8524 | ); | 8522 | ); |
8525 | if ((!exitstatus) == is_or) | 8523 | if (!status == is_or || evalskip) |
8526 | break; | 8524 | break; |
8527 | if (!evalskip) { | 8525 | n = n->nbinary.ch2; |
8528 | n = n->nbinary.ch2; | ||
8529 | evaln: | 8526 | evaln: |
8530 | evalfn = evaltree; | 8527 | evalfn = evaltree; |
8531 | calleval: | 8528 | calleval: |
8532 | evalfn(n, flags); | 8529 | status = evalfn(n, flags); |
8533 | break; | 8530 | goto setstatus; |
8534 | } | ||
8535 | break; | ||
8536 | } | 8531 | } |
8537 | case NIF: | 8532 | case NIF: |
8538 | evaltree(n->nif.test, EV_TESTED); | 8533 | status = evaltree(n->nif.test, EV_TESTED); |
8539 | if (evalskip) | 8534 | if (evalskip) |
8540 | break; | 8535 | break; |
8541 | if (exitstatus == 0) { | 8536 | if (!status) { |
8542 | n = n->nif.ifpart; | 8537 | n = n->nif.ifpart; |
8543 | goto evaln; | 8538 | goto evaln; |
8544 | } | 8539 | } |
@@ -8546,11 +8541,14 @@ evaltree(union node *n, int flags) | |||
8546 | n = n->nif.elsepart; | 8541 | n = n->nif.elsepart; |
8547 | goto evaln; | 8542 | goto evaln; |
8548 | } | 8543 | } |
8549 | goto success; | 8544 | status = 0; |
8545 | goto setstatus; | ||
8550 | case NDEFUN: | 8546 | case NDEFUN: |
8551 | defun(n->narg.text, n->narg.next); | 8547 | defun(n->narg.text, n->narg.next); |
8552 | success: | 8548 | /* Not necessary. To test it: |
8553 | status = 0; | 8549 | * "false; f() { qwerty; }; echo $?" should print 0. |
8550 | */ | ||
8551 | /* status = 0; */ | ||
8554 | setstatus: | 8552 | setstatus: |
8555 | exitstatus = status; | 8553 | exitstatus = status; |
8556 | break; | 8554 | break; |
@@ -8565,7 +8563,7 @@ evaltree(union node *n, int flags) | |||
8565 | */ | 8563 | */ |
8566 | if (pending_sig && dotrap()) | 8564 | if (pending_sig && dotrap()) |
8567 | goto exexit; | 8565 | goto exexit; |
8568 | if (checkexit & exitstatus) | 8566 | if (checkexit & status) |
8569 | evalskip |= SKIPEVAL; | 8567 | evalskip |= SKIPEVAL; |
8570 | 8568 | ||
8571 | if (flags & EV_EXIT) { | 8569 | if (flags & EV_EXIT) { |
@@ -8575,14 +8573,16 @@ evaltree(union node *n, int flags) | |||
8575 | 8573 | ||
8576 | RESTORE_INT(int_level); | 8574 | RESTORE_INT(int_level); |
8577 | TRACE(("leaving evaltree (no interrupts)\n")); | 8575 | TRACE(("leaving evaltree (no interrupts)\n")); |
8576 | |||
8577 | return exitstatus; | ||
8578 | } | 8578 | } |
8579 | 8579 | ||
8580 | #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3) | 8580 | #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3) |
8581 | static | 8581 | static |
8582 | #endif | 8582 | #endif |
8583 | void evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__)); | 8583 | int evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__)); |
8584 | 8584 | ||
8585 | static void | 8585 | static int |
8586 | evalloop(union node *n, int flags) | 8586 | evalloop(union node *n, int flags) |
8587 | { | 8587 | { |
8588 | int status; | 8588 | int status; |
@@ -8593,7 +8593,7 @@ evalloop(union node *n, int flags) | |||
8593 | for (;;) { | 8593 | for (;;) { |
8594 | int i; | 8594 | int i; |
8595 | 8595 | ||
8596 | evaltree(n->nbinary.ch1, EV_TESTED); | 8596 | i = evaltree(n->nbinary.ch1, EV_TESTED); |
8597 | if (evalskip) { | 8597 | if (evalskip) { |
8598 | skipping: | 8598 | skipping: |
8599 | if (evalskip == SKIPCONT && --skipcount <= 0) { | 8599 | if (evalskip == SKIPCONT && --skipcount <= 0) { |
@@ -8604,27 +8604,28 @@ evalloop(union node *n, int flags) | |||
8604 | evalskip = 0; | 8604 | evalskip = 0; |
8605 | break; | 8605 | break; |
8606 | } | 8606 | } |
8607 | i = exitstatus; | ||
8608 | if (n->type != NWHILE) | 8607 | if (n->type != NWHILE) |
8609 | i = !i; | 8608 | i = !i; |
8610 | if (i != 0) | 8609 | if (i != 0) |
8611 | break; | 8610 | break; |
8612 | evaltree(n->nbinary.ch2, flags); | 8611 | status = evaltree(n->nbinary.ch2, flags); |
8613 | status = exitstatus; | ||
8614 | if (evalskip) | 8612 | if (evalskip) |
8615 | goto skipping; | 8613 | goto skipping; |
8616 | } | 8614 | } |
8617 | loopnest--; | ||
8618 | exitstatus = status; | 8615 | exitstatus = status; |
8616 | loopnest--; | ||
8617 | |||
8618 | return status; | ||
8619 | } | 8619 | } |
8620 | 8620 | ||
8621 | static void | 8621 | static int |
8622 | evalfor(union node *n, int flags) | 8622 | evalfor(union node *n, int flags) |
8623 | { | 8623 | { |
8624 | struct arglist arglist; | 8624 | struct arglist arglist; |
8625 | union node *argp; | 8625 | union node *argp; |
8626 | struct strlist *sp; | 8626 | struct strlist *sp; |
8627 | struct stackmark smark; | 8627 | struct stackmark smark; |
8628 | int status = 0; | ||
8628 | 8629 | ||
8629 | setstackmark(&smark); | 8630 | setstackmark(&smark); |
8630 | arglist.list = NULL; | 8631 | arglist.list = NULL; |
@@ -8637,12 +8638,11 @@ evalfor(union node *n, int flags) | |||
8637 | } | 8638 | } |
8638 | *arglist.lastp = NULL; | 8639 | *arglist.lastp = NULL; |
8639 | 8640 | ||
8640 | exitstatus = 0; | ||
8641 | loopnest++; | 8641 | loopnest++; |
8642 | flags &= EV_TESTED; | 8642 | flags &= EV_TESTED; |
8643 | for (sp = arglist.list; sp; sp = sp->next) { | 8643 | for (sp = arglist.list; sp; sp = sp->next) { |
8644 | setvar0(n->nfor.var, sp->text); | 8644 | setvar0(n->nfor.var, sp->text); |
8645 | evaltree(n->nfor.body, flags); | 8645 | status = evaltree(n->nfor.body, flags); |
8646 | if (evalskip) { | 8646 | if (evalskip) { |
8647 | if (evalskip == SKIPCONT && --skipcount <= 0) { | 8647 | if (evalskip == SKIPCONT && --skipcount <= 0) { |
8648 | evalskip = 0; | 8648 | evalskip = 0; |
@@ -8656,26 +8656,32 @@ evalfor(union node *n, int flags) | |||
8656 | loopnest--; | 8656 | loopnest--; |
8657 | out: | 8657 | out: |
8658 | popstackmark(&smark); | 8658 | popstackmark(&smark); |
8659 | |||
8660 | return status; | ||
8659 | } | 8661 | } |
8660 | 8662 | ||
8661 | static void | 8663 | static int |
8662 | evalcase(union node *n, int flags) | 8664 | evalcase(union node *n, int flags) |
8663 | { | 8665 | { |
8664 | union node *cp; | 8666 | union node *cp; |
8665 | union node *patp; | 8667 | union node *patp; |
8666 | struct arglist arglist; | 8668 | struct arglist arglist; |
8667 | struct stackmark smark; | 8669 | struct stackmark smark; |
8670 | int status = 0; | ||
8668 | 8671 | ||
8669 | setstackmark(&smark); | 8672 | setstackmark(&smark); |
8670 | arglist.list = NULL; | 8673 | arglist.list = NULL; |
8671 | arglist.lastp = &arglist.list; | 8674 | arglist.lastp = &arglist.list; |
8672 | expandarg(n->ncase.expr, &arglist, EXP_TILDE); | 8675 | expandarg(n->ncase.expr, &arglist, EXP_TILDE); |
8673 | exitstatus = 0; | ||
8674 | for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) { | 8676 | for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) { |
8675 | for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) { | 8677 | for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) { |
8676 | if (casematch(patp, arglist.list->text)) { | 8678 | if (casematch(patp, arglist.list->text)) { |
8677 | if (evalskip == 0) { | 8679 | /* Ensure body is non-empty as otherwise |
8678 | evaltree(cp->nclist.body, flags); | 8680 | * EV_EXIT may prevent us from setting the |
8681 | * exit status. | ||
8682 | */ | ||
8683 | if (evalskip == 0 && cp->nclist.body) { | ||
8684 | status = evaltree(cp->nclist.body, flags); | ||
8679 | } | 8685 | } |
8680 | goto out; | 8686 | goto out; |
8681 | } | 8687 | } |
@@ -8683,12 +8689,14 @@ evalcase(union node *n, int flags) | |||
8683 | } | 8689 | } |
8684 | out: | 8690 | out: |
8685 | popstackmark(&smark); | 8691 | popstackmark(&smark); |
8692 | |||
8693 | return status; | ||
8686 | } | 8694 | } |
8687 | 8695 | ||
8688 | /* | 8696 | /* |
8689 | * Kick off a subshell to evaluate a tree. | 8697 | * Kick off a subshell to evaluate a tree. |
8690 | */ | 8698 | */ |
8691 | static void | 8699 | static int |
8692 | evalsubshell(union node *n, int flags) | 8700 | evalsubshell(union node *n, int flags) |
8693 | { | 8701 | { |
8694 | struct job *jp; | 8702 | struct job *jp; |
@@ -8714,8 +8722,8 @@ evalsubshell(union node *n, int flags) | |||
8714 | status = 0; | 8722 | status = 0; |
8715 | if (!backgnd) | 8723 | if (!backgnd) |
8716 | status = waitforjob(jp); | 8724 | status = waitforjob(jp); |
8717 | exitstatus = status; | ||
8718 | INT_ON; | 8725 | INT_ON; |
8726 | return status; | ||
8719 | } | 8727 | } |
8720 | 8728 | ||
8721 | /* | 8729 | /* |
@@ -8788,7 +8796,7 @@ expredir(union node *n) | |||
8788 | * of the shell, which make the last process in a pipeline the parent | 8796 | * of the shell, which make the last process in a pipeline the parent |
8789 | * of all the rest.) | 8797 | * of all the rest.) |
8790 | */ | 8798 | */ |
8791 | static void | 8799 | static int |
8792 | evalpipe(union node *n, int flags) | 8800 | evalpipe(union node *n, int flags) |
8793 | { | 8801 | { |
8794 | struct job *jp; | 8802 | struct job *jp; |
@@ -8796,6 +8804,7 @@ evalpipe(union node *n, int flags) | |||
8796 | int pipelen; | 8804 | int pipelen; |
8797 | int prevfd; | 8805 | int prevfd; |
8798 | int pip[2]; | 8806 | int pip[2]; |
8807 | int status = 0; | ||
8799 | 8808 | ||
8800 | TRACE(("evalpipe(0x%lx) called\n", (long)n)); | 8809 | TRACE(("evalpipe(0x%lx) called\n", (long)n)); |
8801 | pipelen = 0; | 8810 | pipelen = 0; |
@@ -8838,10 +8847,12 @@ evalpipe(union node *n, int flags) | |||
8838 | close(pip[1]); | 8847 | close(pip[1]); |
8839 | } | 8848 | } |
8840 | if (n->npipe.pipe_backgnd == 0) { | 8849 | if (n->npipe.pipe_backgnd == 0) { |
8841 | exitstatus = waitforjob(jp); | 8850 | status = waitforjob(jp); |
8842 | TRACE(("evalpipe: job done exit status %d\n", exitstatus)); | 8851 | TRACE(("evalpipe: job done exit status %d\n", status)); |
8843 | } | 8852 | } |
8844 | INT_ON; | 8853 | INT_ON; |
8854 | |||
8855 | return status; | ||
8845 | } | 8856 | } |
8846 | 8857 | ||
8847 | /* | 8858 | /* |
@@ -9328,7 +9339,7 @@ bltincmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
9328 | * as POSIX mandates */ | 9339 | * as POSIX mandates */ |
9329 | return back_exitstatus; | 9340 | return back_exitstatus; |
9330 | } | 9341 | } |
9331 | static void | 9342 | static int |
9332 | evalcommand(union node *cmd, int flags) | 9343 | evalcommand(union node *cmd, int flags) |
9333 | { | 9344 | { |
9334 | static const struct builtincmd null_bltin = { | 9345 | static const struct builtincmd null_bltin = { |
@@ -9511,9 +9522,9 @@ evalcommand(union node *cmd, int flags) | |||
9511 | jp = makejob(/*cmd,*/ 1); | 9522 | jp = makejob(/*cmd,*/ 1); |
9512 | if (forkshell(jp, cmd, FORK_FG) != 0) { | 9523 | if (forkshell(jp, cmd, FORK_FG) != 0) { |
9513 | /* parent */ | 9524 | /* parent */ |
9514 | exitstatus = waitforjob(jp); | 9525 | status = waitforjob(jp); |
9515 | INT_ON; | 9526 | INT_ON; |
9516 | TRACE(("forked child exited with %d\n", exitstatus)); | 9527 | TRACE(("forked child exited with %d\n", status)); |
9517 | break; | 9528 | break; |
9518 | } | 9529 | } |
9519 | /* child */ | 9530 | /* child */ |
@@ -9559,7 +9570,7 @@ evalcommand(union node *cmd, int flags) | |||
9559 | } | 9570 | } |
9560 | FORCE_INT_ON; | 9571 | FORCE_INT_ON; |
9561 | } | 9572 | } |
9562 | break; | 9573 | goto readstatus; |
9563 | 9574 | ||
9564 | case CMDFUNCTION: | 9575 | case CMDFUNCTION: |
9565 | listsetvar(varlist.list, 0); | 9576 | listsetvar(varlist.list, 0); |
@@ -9567,6 +9578,8 @@ evalcommand(union node *cmd, int flags) | |||
9567 | dowait(DOWAIT_NONBLOCK, NULL); | 9578 | dowait(DOWAIT_NONBLOCK, NULL); |
9568 | if (evalfun(cmdentry.u.func, argc, argv, flags)) | 9579 | if (evalfun(cmdentry.u.func, argc, argv, flags)) |
9569 | goto raise; | 9580 | goto raise; |
9581 | readstatus: | ||
9582 | status = exitstatus; | ||
9570 | break; | 9583 | break; |
9571 | } /* switch */ | 9584 | } /* switch */ |
9572 | 9585 | ||
@@ -9580,6 +9593,8 @@ evalcommand(union node *cmd, int flags) | |||
9580 | setvar0("_", lastarg); | 9593 | setvar0("_", lastarg); |
9581 | } | 9594 | } |
9582 | popstackmark(&smark); | 9595 | popstackmark(&smark); |
9596 | |||
9597 | return status; | ||
9583 | } | 9598 | } |
9584 | 9599 | ||
9585 | static int | 9600 | static int |
@@ -12205,13 +12220,18 @@ evalstring(char *s, int mask) | |||
12205 | union node *n; | 12220 | union node *n; |
12206 | struct stackmark smark; | 12221 | struct stackmark smark; |
12207 | int skip; | 12222 | int skip; |
12223 | // int status; | ||
12208 | 12224 | ||
12209 | setinputstring(s); | 12225 | setinputstring(s); |
12210 | setstackmark(&smark); | 12226 | setstackmark(&smark); |
12211 | 12227 | ||
12212 | skip = 0; | 12228 | skip = 0; |
12213 | while ((n = parsecmd(0)) != NODE_EOF) { | 12229 | while ((n = parsecmd(0)) != NODE_EOF) { |
12214 | evaltree(n, 0); | 12230 | int i; |
12231 | |||
12232 | i = evaltree(n, 0); | ||
12233 | // if (n) | ||
12234 | // status = i; | ||
12215 | popstackmark(&smark); | 12235 | popstackmark(&smark); |
12216 | skip = evalskip; | 12236 | skip = evalskip; |
12217 | if (skip) | 12237 | if (skip) |
@@ -12222,6 +12242,7 @@ evalstring(char *s, int mask) | |||
12222 | skip &= mask; | 12242 | skip &= mask; |
12223 | evalskip = skip; | 12243 | evalskip = skip; |
12224 | return skip; | 12244 | return skip; |
12245 | // return status; | ||
12225 | } | 12246 | } |
12226 | 12247 | ||
12227 | /* | 12248 | /* |
@@ -12264,6 +12285,7 @@ cmdloop(int top) | |||
12264 | union node *n; | 12285 | union node *n; |
12265 | struct stackmark smark; | 12286 | struct stackmark smark; |
12266 | int inter; | 12287 | int inter; |
12288 | int status = 0; | ||
12267 | int numeof = 0; | 12289 | int numeof = 0; |
12268 | 12290 | ||
12269 | TRACE(("cmdloop(%d) called\n", top)); | 12291 | TRACE(("cmdloop(%d) called\n", top)); |
@@ -12295,10 +12317,14 @@ cmdloop(int top) | |||
12295 | } | 12317 | } |
12296 | numeof++; | 12318 | numeof++; |
12297 | } else if (nflag == 0) { | 12319 | } else if (nflag == 0) { |
12320 | int i; | ||
12321 | |||
12298 | /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */ | 12322 | /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */ |
12299 | job_warning >>= 1; | 12323 | job_warning >>= 1; |
12300 | numeof = 0; | 12324 | numeof = 0; |
12301 | evaltree(n, 0); | 12325 | i = evaltree(n, 0); |
12326 | if (n) | ||
12327 | status = i; | ||
12302 | } | 12328 | } |
12303 | popstackmark(&smark); | 12329 | popstackmark(&smark); |
12304 | skip = evalskip; | 12330 | skip = evalskip; |
@@ -12308,7 +12334,7 @@ cmdloop(int top) | |||
12308 | return skip & SKIPEVAL; | 12334 | return skip & SKIPEVAL; |
12309 | } | 12335 | } |
12310 | } | 12336 | } |
12311 | return 0; | 12337 | return status; |
12312 | } | 12338 | } |
12313 | 12339 | ||
12314 | /* | 12340 | /* |
diff --git a/shell/ash_test/ash-misc/exitcode1.right b/shell/ash_test/ash-misc/exitcode1.right new file mode 100644 index 000000000..e5fefefda --- /dev/null +++ b/shell/ash_test/ash-misc/exitcode1.right | |||
@@ -0,0 +1,2 @@ | |||
1 | One:1 | ||
2 | Zero:0 | ||
diff --git a/shell/ash_test/ash-misc/exitcode1.tests b/shell/ash_test/ash-misc/exitcode1.tests new file mode 100755 index 000000000..dc8619d8b --- /dev/null +++ b/shell/ash_test/ash-misc/exitcode1.tests | |||
@@ -0,0 +1,2 @@ | |||
1 | false || case a in a) echo One:$?;; esac | ||
2 | echo Zero:$? | ||
diff --git a/shell/hush_test/hush-misc/exitcode1.right b/shell/hush_test/hush-misc/exitcode1.right new file mode 100644 index 000000000..e5fefefda --- /dev/null +++ b/shell/hush_test/hush-misc/exitcode1.right | |||
@@ -0,0 +1,2 @@ | |||
1 | One:1 | ||
2 | Zero:0 | ||
diff --git a/shell/hush_test/hush-misc/exitcode1.tests b/shell/hush_test/hush-misc/exitcode1.tests new file mode 100755 index 000000000..dc8619d8b --- /dev/null +++ b/shell/hush_test/hush-misc/exitcode1.tests | |||
@@ -0,0 +1,2 @@ | |||
1 | false || case a in a) echo One:$?;; esac | ||
2 | echo Zero:$? | ||