diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-04 20:14:04 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-04 20:14:04 +0100 |
commit | aeaee43d5a4fc95405cc2047227d096b1ada55b6 (patch) | |
tree | 3b98a3650e486dde735a4e24a367d3622a985e13 | |
parent | 30bfcf612b0862e4dd98d923eabb308b54012d24 (diff) | |
download | busybox-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.c | 16 |
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 |