aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-28 15:43:50 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-28 15:43:50 +0200
commitd81e9f5093b222369d510d0b1c0587a411e4c83e (patch)
treea81dea56de47b2578497dd5e31537e6601784d3b
parent458c1f218bb6a6bd0325f0b0cedea5ab0980dbc3 (diff)
downloadbusybox-w32-d81e9f5093b222369d510d0b1c0587a411e4c83e.tar.gz
busybox-w32-d81e9f5093b222369d510d0b1c0587a411e4c83e.tar.bz2
busybox-w32-d81e9f5093b222369d510d0b1c0587a411e4c83e.zip
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>
-rw-r--r--shell/ash.c25
-rw-r--r--shell/ash_test/ash-vars/readonly1.right2
-rwxr-xr-xshell/ash_test/ash-vars/readonly1.tests7
3 files changed, 33 insertions, 1 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 1ef02b8be..fe112453c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2180,6 +2180,7 @@ setvareq(char *s, int flags)
2180 if (flags & VNOSAVE) 2180 if (flags & VNOSAVE)
2181 free(s); 2181 free(s);
2182 n = vp->var_text; 2182 n = vp->var_text;
2183 exitstatus = 1;
2183 ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n); 2184 ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
2184 } 2185 }
2185 2186
@@ -9599,7 +9600,7 @@ evalcommand(union node *cmd, int flags)
9599 if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) { 9600 if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
9600 if (exception_type == EXERROR && spclbltin <= 0) { 9601 if (exception_type == EXERROR && spclbltin <= 0) {
9601 FORCE_INT_ON; 9602 FORCE_INT_ON;
9602 break; 9603 goto readstatus;
9603 } 9604 }
9604 raise: 9605 raise:
9605 longjmp(exception_handler->loc, 1); 9606 longjmp(exception_handler->loc, 1);
@@ -12280,6 +12281,10 @@ expandstr(const char *ps)
12280static int 12281static int
12281evalstring(char *s, int flags) 12282evalstring(char *s, int flags)
12282{ 12283{
12284 struct jmploc *volatile savehandler = exception_handler;
12285 struct jmploc jmploc;
12286 int ex;
12287
12283 union node *n; 12288 union node *n;
12284 struct stackmark smark; 12289 struct stackmark smark;
12285 int status; 12290 int status;
@@ -12289,6 +12294,19 @@ evalstring(char *s, int flags)
12289 setstackmark(&smark); 12294 setstackmark(&smark);
12290 12295
12291 status = 0; 12296 status = 0;
12297 /* On exception inside execution loop, we must popfile().
12298 * Try interactively:
12299 * readonly a=a
12300 * command eval "a=b" # throws "is read only" error
12301 * "command BLTIN" is not supposed to abort (even in non-interactive use).
12302 * But if we skip popfile(), we hit EOF in eval's string, and exit.
12303 */
12304 savehandler = exception_handler;
12305 exception_handler = &jmploc;
12306 ex = setjmp(jmploc.loc);
12307 if (ex)
12308 goto out;
12309
12292 while ((n = parsecmd(0)) != NODE_EOF) { 12310 while ((n = parsecmd(0)) != NODE_EOF) {
12293 int i; 12311 int i;
12294 12312
@@ -12299,10 +12317,15 @@ evalstring(char *s, int flags)
12299 if (evalskip) 12317 if (evalskip)
12300 break; 12318 break;
12301 } 12319 }
12320 out:
12302 popstackmark(&smark); 12321 popstackmark(&smark);
12303 popfile(); 12322 popfile();
12304 stunalloc(s); 12323 stunalloc(s);
12305 12324
12325 exception_handler = savehandler;
12326 if (ex)
12327 longjmp(exception_handler->loc, ex);
12328
12306 return status; 12329 return status;
12307} 12330}
12308 12331
diff --git a/shell/ash_test/ash-vars/readonly1.right b/shell/ash_test/ash-vars/readonly1.right
new file mode 100644
index 000000000..2b363e325
--- /dev/null
+++ b/shell/ash_test/ash-vars/readonly1.right
@@ -0,0 +1,2 @@
1One:1
2One:1
diff --git a/shell/ash_test/ash-vars/readonly1.tests b/shell/ash_test/ash-vars/readonly1.tests
new file mode 100755
index 000000000..81b461f5f
--- /dev/null
+++ b/shell/ash_test/ash-vars/readonly1.tests
@@ -0,0 +1,7 @@
1readonly bla=123
2# Bare "eval bla=123" should abort ("eval" is a special builtin):
3(eval bla=123 2>/dev/null; echo BUG)
4echo One:$?
5# "command BLTIN" disables "special-ness", should not abort:
6command eval bla=123 2>/dev/null
7echo One:$?