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:
		
							
								
								
									
										16
									
								
								shell/hush.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								shell/hush.c
									
									
									
									
									
								
							| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user