aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-05-18 16:13:56 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-05-18 16:13:56 +0200
commit42c4b2e3b535314ae8a7b65c3223afb26872d5a2 (patch)
tree8c0d1b5eef44dc9dbce6788fe41db1af22bbf470 /shell
parentc7f95d23f6bc7e17a3b79decf83eb362b389e53a (diff)
downloadbusybox-w32-42c4b2e3b535314ae8a7b65c3223afb26872d5a2.tar.gz
busybox-w32-42c4b2e3b535314ae8a7b65c3223afb26872d5a2.tar.bz2
busybox-w32-42c4b2e3b535314ae8a7b65c3223afb26872d5a2.zip
ash: fix var_leak.tests so that it actually catches the NOFORK bug
+ document the bug better Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c22
-rw-r--r--shell/ash_test/ash-vars/var_leak.right1
-rwxr-xr-xshell/ash_test/ash-vars/var_leak.tests7
3 files changed, 21 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c
index d082333ba..83886c610 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9179,12 +9179,14 @@ evalcommand(union node *cmd, int flags)
9179 9179
9180 /* Execute the command. */ 9180 /* Execute the command. */
9181 switch (cmdentry.cmdtype) { 9181 switch (cmdentry.cmdtype) {
9182 default: 9182 default: {
9183 9183
9184#if ENABLE_FEATURE_SH_NOFORK 9184#if ENABLE_FEATURE_SH_NOFORK
9185/* Hmmm... shouldn't it happen somewhere in forkshell() instead? 9185/* (1) BUG: if variables are set, we need to fork, or save/restore them
9186 * Why "fork off a child process if necessary" doesn't apply to NOFORK? */ 9186 * around run_nofork_applet() call.
9187 { 9187 * (2) Should this check also be done in forkshell()?
9188 * (perhaps it should, so that "VAR=VAL nofork" at least avoids exec...)
9189 */
9188 /* find_command() encodes applet_no as (-2 - applet_no) */ 9190 /* find_command() encodes applet_no as (-2 - applet_no) */
9189 int applet_no = (- cmdentry.u.index - 2); 9191 int applet_no = (- cmdentry.u.index - 2);
9190 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) { 9192 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
@@ -9193,10 +9195,13 @@ evalcommand(union node *cmd, int flags)
9193 exitstatus = run_nofork_applet(applet_no, argv); 9195 exitstatus = run_nofork_applet(applet_no, argv);
9194 break; 9196 break;
9195 } 9197 }
9196 }
9197#endif 9198#endif
9198 /* Fork off a child process if necessary. */ 9199 /* Can we avoid forking off? For example, very last command
9200 * in a script or a subshell does not need forking,
9201 * we can just exec it.
9202 */
9199 if (!(flags & EV_EXIT) || may_have_traps) { 9203 if (!(flags & EV_EXIT) || may_have_traps) {
9204 /* No, forking off a child is necessary */
9200 INT_OFF; 9205 INT_OFF;
9201 jp = makejob(/*cmd,*/ 1); 9206 jp = makejob(/*cmd,*/ 1);
9202 if (forkshell(jp, cmd, FORK_FG) != 0) { 9207 if (forkshell(jp, cmd, FORK_FG) != 0) {
@@ -9213,7 +9218,7 @@ evalcommand(union node *cmd, int flags)
9213 listsetvar(varlist.list, VEXPORT|VSTACK); 9218 listsetvar(varlist.list, VEXPORT|VSTACK);
9214 shellexec(argv, path, cmdentry.u.index); 9219 shellexec(argv, path, cmdentry.u.index);
9215 /* NOTREACHED */ 9220 /* NOTREACHED */
9216 9221 } /* default */
9217 case CMDBUILTIN: 9222 case CMDBUILTIN:
9218 cmdenviron = varlist.list; 9223 cmdenviron = varlist.list;
9219 if (cmdenviron) { 9224 if (cmdenviron) {
@@ -9258,7 +9263,8 @@ evalcommand(union node *cmd, int flags)
9258 if (evalfun(cmdentry.u.func, argc, argv, flags)) 9263 if (evalfun(cmdentry.u.func, argc, argv, flags))
9259 goto raise; 9264 goto raise;
9260 break; 9265 break;
9261 } 9266
9267 } /* switch */
9262 9268
9263 out: 9269 out:
9264 popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec); 9270 popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec);
diff --git a/shell/ash_test/ash-vars/var_leak.right b/shell/ash_test/ash-vars/var_leak.right
index be78112c8..01a5e3263 100644
--- a/shell/ash_test/ash-vars/var_leak.right
+++ b/shell/ash_test/ash-vars/var_leak.right
@@ -1,3 +1,4 @@
1should be empty: '' 1should be empty: ''
2should be empty: ''
2should be not empty: 'val2' 3should be not empty: 'val2'
3should be not empty: 'val3' 4should be not empty: 'val3'
diff --git a/shell/ash_test/ash-vars/var_leak.tests b/shell/ash_test/ash-vars/var_leak.tests
index 032059295..5242e24eb 100755
--- a/shell/ash_test/ash-vars/var_leak.tests
+++ b/shell/ash_test/ash-vars/var_leak.tests
@@ -1,6 +1,11 @@
1# true is a regular builtin, varibale should not leak out of it 1# cat is an external program, variable should not leak out of it.
2# this currently fails with CONFIG_FEATURE_SH_NOFORK=y 2# this currently fails with CONFIG_FEATURE_SH_NOFORK=y
3VAR='' 3VAR=''
4VAR=val0 cat /dev/null
5echo "should be empty: '$VAR'"
6
7# true is a regular builtin, variable should not leak out of it.
8VAR=''
4VAR=val1 true 9VAR=val1 true
5echo "should be empty: '$VAR'" 10echo "should be empty: '$VAR'"
6 11