ash: fix interactive "command eval STRING" exiting on errors.
This bug is also present in current dash Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
		
							
								
								
									
										25
									
								
								shell/ash.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								shell/ash.c
									
									
									
									
									
								
							| @@ -2180,6 +2180,7 @@ setvareq(char *s, int flags) | ||||
| 			if (flags & VNOSAVE) | ||||
| 				free(s); | ||||
| 			n = vp->var_text; | ||||
| 			exitstatus = 1; | ||||
| 			ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n); | ||||
| 		} | ||||
|  | ||||
| @@ -9599,7 +9600,7 @@ evalcommand(union node *cmd, int flags) | ||||
| 		if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) { | ||||
| 			if (exception_type == EXERROR && spclbltin <= 0) { | ||||
| 				FORCE_INT_ON; | ||||
| 				break; | ||||
| 				goto readstatus; | ||||
| 			} | ||||
|  raise: | ||||
| 			longjmp(exception_handler->loc, 1); | ||||
| @@ -12280,6 +12281,10 @@ expandstr(const char *ps) | ||||
| static int | ||||
| evalstring(char *s, int flags) | ||||
| { | ||||
| 	struct jmploc *volatile savehandler = exception_handler; | ||||
| 	struct jmploc jmploc; | ||||
| 	int ex; | ||||
|  | ||||
| 	union node *n; | ||||
| 	struct stackmark smark; | ||||
| 	int status; | ||||
| @@ -12289,6 +12294,19 @@ evalstring(char *s, int flags) | ||||
| 	setstackmark(&smark); | ||||
|  | ||||
| 	status = 0; | ||||
| 	/* On exception inside execution loop, we must popfile(). | ||||
| 	 * Try interactively: | ||||
| 	 *	readonly a=a | ||||
| 	 *	command eval "a=b"  # throws "is read only" error | ||||
| 	 * "command BLTIN" is not supposed to abort (even in non-interactive use). | ||||
| 	 * But if we skip popfile(), we hit EOF in eval's string, and exit. | ||||
| 	 */ | ||||
| 	savehandler = exception_handler; | ||||
| 	exception_handler = &jmploc; | ||||
| 	ex = setjmp(jmploc.loc); | ||||
| 	if (ex) | ||||
| 		goto out; | ||||
|  | ||||
| 	while ((n = parsecmd(0)) != NODE_EOF) { | ||||
| 		int i; | ||||
|  | ||||
| @@ -12299,10 +12317,15 @@ evalstring(char *s, int flags) | ||||
| 		if (evalskip) | ||||
| 			break; | ||||
| 	} | ||||
|  out: | ||||
| 	popstackmark(&smark); | ||||
| 	popfile(); | ||||
| 	stunalloc(s); | ||||
|  | ||||
| 	exception_handler = savehandler; | ||||
| 	if (ex) | ||||
|                 longjmp(exception_handler->loc, ex); | ||||
|  | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								shell/ash_test/ash-vars/readonly1.right
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								shell/ash_test/ash-vars/readonly1.right
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| One:1 | ||||
| One:1 | ||||
							
								
								
									
										7
									
								
								shell/ash_test/ash-vars/readonly1.tests
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								shell/ash_test/ash-vars/readonly1.tests
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| readonly bla=123 | ||||
| # Bare "eval bla=123" should abort ("eval" is a special builtin): | ||||
| (eval bla=123 2>/dev/null; echo BUG) | ||||
| echo One:$? | ||||
| # "command BLTIN" disables "special-ness", should not abort: | ||||
| command eval bla=123 2>/dev/null | ||||
| echo One:$? | ||||
		Reference in New Issue
	
	Block a user