aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-11-04 20:14:04 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2016-11-04 20:14:04 +0100
commitaeaee43d5a4fc95405cc2047227d096b1ada55b6 (patch)
tree3b98a3650e486dde735a4e24a367d3622a985e13
parent30bfcf612b0862e4dd98d923eabb308b54012d24 (diff)
downloadbusybox-w32-aeaee43d5a4fc95405cc2047227d096b1ada55b6.tar.gz
busybox-w32-aeaee43d5a4fc95405cc2047227d096b1ada55b6.tar.bz2
busybox-w32-aeaee43d5a4fc95405cc2047227d096b1ada55b6.zip
hush: case logic for setting $? was still wrong
Resetting to 0 should happen in "esac". Matched branch must still see previous $?. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 4c2ed6cea..0bc67ecc9 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -7874,14 +7874,14 @@ static int run_list(struct pipe *pi)
7874#endif 7874#endif
7875#if ENABLE_HUSH_CASE 7875#if ENABLE_HUSH_CASE
7876 if (rword == RES_CASE) { 7876 if (rword == RES_CASE) {
7877 /* Case which does not match and execute anything still sets $? to 0 */ 7877 debug_printf_exec("CASE cond_code:%d\n", cond_code);
7878 G.last_exitcode = rcode = EXIT_SUCCESS;
7879 case_word = expand_strvec_to_string(pi->cmds->argv); 7878 case_word = expand_strvec_to_string(pi->cmds->argv);
7880 continue; 7879 continue;
7881 } 7880 }
7882 if (rword == RES_MATCH) { 7881 if (rword == RES_MATCH) {
7883 char **argv; 7882 char **argv;
7884 7883
7884 debug_printf_exec("MATCH cond_code:%d\n", cond_code);
7885 if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */ 7885 if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
7886 break; 7886 break;
7887 /* all prev words didn't match, does this one match? */ 7887 /* all prev words didn't match, does this one match? */
@@ -7892,8 +7892,8 @@ static int run_list(struct pipe *pi)
7892 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); 7892 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
7893 free(pattern); 7893 free(pattern);
7894 if (cond_code == 0) { /* match! we will execute this branch */ 7894 if (cond_code == 0) { /* match! we will execute this branch */
7895 free(case_word); /* make future "word)" stop */ 7895 free(case_word);
7896 case_word = NULL; 7896 case_word = NULL; /* make future "word)" stop */
7897 break; 7897 break;
7898 } 7898 }
7899 argv++; 7899 argv++;
@@ -7901,9 +7901,17 @@ static int run_list(struct pipe *pi)
7901 continue; 7901 continue;
7902 } 7902 }
7903 if (rword == RES_CASE_BODY) { /* inside of a case branch */ 7903 if (rword == RES_CASE_BODY) { /* inside of a case branch */
7904 debug_printf_exec("CASE_BODY cond_code:%d\n", cond_code);
7904 if (cond_code != 0) 7905 if (cond_code != 0)
7905 continue; /* not matched yet, skip this pipe */ 7906 continue; /* not matched yet, skip this pipe */
7906 } 7907 }
7908 if (rword == RES_ESAC) {
7909 debug_printf_exec("ESAC cond_code:%d\n", cond_code);
7910 if (case_word) {
7911 /* "case" did not match anything: still set $? (to 0) */
7912 G.last_exitcode = rcode = EXIT_SUCCESS;
7913 }
7914 }
7907#endif 7915#endif
7908 /* Just pressing <enter> in shell should check for jobs. 7916 /* Just pressing <enter> in shell should check for jobs.
7909 * OTOH, in non-interactive shell this is useless 7917 * OTOH, in non-interactive shell this is useless