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>
This commit is contained in:
Denys Vlasenko 2016-11-04 20:14:04 +01:00
parent 30bfcf612b
commit aeaee43d5a

View File

@ -7874,14 +7874,14 @@ static int run_list(struct pipe *pi)
#endif #endif
#if ENABLE_HUSH_CASE #if ENABLE_HUSH_CASE
if (rword == RES_CASE) { if (rword == RES_CASE) {
/* Case which does not match and execute anything still sets $? to 0 */ debug_printf_exec("CASE cond_code:%d\n", cond_code);
G.last_exitcode = rcode = EXIT_SUCCESS;
case_word = expand_strvec_to_string(pi->cmds->argv); case_word = expand_strvec_to_string(pi->cmds->argv);
continue; continue;
} }
if (rword == RES_MATCH) { if (rword == RES_MATCH) {
char **argv; char **argv;
debug_printf_exec("MATCH cond_code:%d\n", cond_code);
if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */ if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
break; break;
/* all prev words didn't match, does this one match? */ /* all prev words didn't match, does this one match? */
@ -7892,8 +7892,8 @@ static int run_list(struct pipe *pi)
cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
free(pattern); free(pattern);
if (cond_code == 0) { /* match! we will execute this branch */ if (cond_code == 0) { /* match! we will execute this branch */
free(case_word); /* make future "word)" stop */ free(case_word);
case_word = NULL; case_word = NULL; /* make future "word)" stop */
break; break;
} }
argv++; argv++;
@ -7901,9 +7901,17 @@ static int run_list(struct pipe *pi)
continue; continue;
} }
if (rword == RES_CASE_BODY) { /* inside of a case branch */ if (rword == RES_CASE_BODY) { /* inside of a case branch */
debug_printf_exec("CASE_BODY cond_code:%d\n", cond_code);
if (cond_code != 0) if (cond_code != 0)
continue; /* not matched yet, skip this pipe */ continue; /* not matched yet, skip this pipe */
} }
if (rword == RES_ESAC) {
debug_printf_exec("ESAC cond_code:%d\n", cond_code);
if (case_word) {
/* "case" did not match anything: still set $? (to 0) */
G.last_exitcode = rcode = EXIT_SUCCESS;
}
}
#endif #endif
/* Just pressing <enter> in shell should check for jobs. /* Just pressing <enter> in shell should check for jobs.
* OTOH, in non-interactive shell this is useless * OTOH, in non-interactive shell this is useless