aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-09-14 11:48:28 +1000
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-09-14 11:48:28 +1000
commitadcaaebedad72991d917fc57348a1b7a87067c2d (patch)
treee3b65813eca78851ac8a723bc3ac972faa43a475
parent743d85e7d1c2a721baf020b9d79f45f0df2420a9 (diff)
parent42c4b2e3b535314ae8a7b65c3223afb26872d5a2 (diff)
downloadbusybox-w32-adcaaebedad72991d917fc57348a1b7a87067c2d.tar.gz
busybox-w32-adcaaebedad72991d917fc57348a1b7a87067c2d.tar.bz2
busybox-w32-adcaaebedad72991d917fc57348a1b7a87067c2d.zip
Merge branch 'origin/master' (early part)
Conflicts: shell/ash.c
-rw-r--r--shell/ash.c23
-rw-r--r--shell/ash_test/ash-vars/var_leak.right1
-rwxr-xr-xshell/ash_test/ash-vars/var_leak.tests7
3 files changed, 22 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 16a331bb0..4e80b097c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9623,12 +9623,14 @@ evalcommand(union node *cmd, int flags)
9623 9623
9624 /* Execute the command. */ 9624 /* Execute the command. */
9625 switch (cmdentry.cmdtype) { 9625 switch (cmdentry.cmdtype) {
9626 default: 9626 default: {
9627 9627
9628#if ENABLE_FEATURE_SH_NOFORK 9628#if ENABLE_FEATURE_SH_NOFORK
9629/* Hmmm... shouldn't it happen somewhere in forkshell() instead? 9629/* (1) BUG: if variables are set, we need to fork, or save/restore them
9630 * Why "fork off a child process if necessary" doesn't apply to NOFORK? */ 9630 * around run_nofork_applet() call.
9631 { 9631 * (2) Should this check also be done in forkshell()?
9632 * (perhaps it should, so that "VAR=VAL nofork" at least avoids exec...)
9633 */
9632 /* find_command() encodes applet_no as (-2 - applet_no) */ 9634 /* find_command() encodes applet_no as (-2 - applet_no) */
9633 int applet_no = (- cmdentry.u.index - 2); 9635 int applet_no = (- cmdentry.u.index - 2);
9634 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) { 9636 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
@@ -9637,10 +9639,14 @@ evalcommand(union node *cmd, int flags)
9637 exitstatus = run_nofork_applet(applet_no, argv); 9639 exitstatus = run_nofork_applet(applet_no, argv);
9638 break; 9640 break;
9639 } 9641 }
9640 }
9641#endif 9642#endif
9643 /* Can we avoid forking off? For example, very last command
9644 * in a script or a subshell does not need forking,
9645 * we can just exec it.
9646 */
9642#if ENABLE_PLATFORM_MINGW32 9647#if ENABLE_PLATFORM_MINGW32
9643 if (!(flags & EV_EXIT) || trap[0]) { 9648 if (!(flags & EV_EXIT) || trap[0]) {
9649 /* No, forking off a child is necessary */
9644 struct forkshell fs; 9650 struct forkshell fs;
9645 9651
9646 memset(&fs, 0, sizeof(fs)); 9652 memset(&fs, 0, sizeof(fs));
@@ -9659,8 +9665,8 @@ evalcommand(union node *cmd, int flags)
9659 } 9665 }
9660 /* goes through to shellexec() */ 9666 /* goes through to shellexec() */
9661#endif 9667#endif
9662 /* Fork off a child process if necessary. */
9663 if (!(flags & EV_EXIT) || may_have_traps) { 9668 if (!(flags & EV_EXIT) || may_have_traps) {
9669 /* No, forking off a child is necessary */
9664 INT_OFF; 9670 INT_OFF;
9665 jp = makejob(/*cmd,*/ 1); 9671 jp = makejob(/*cmd,*/ 1);
9666 if (forkshell(jp, cmd, FORK_FG) != 0) { 9672 if (forkshell(jp, cmd, FORK_FG) != 0) {
@@ -9677,7 +9683,7 @@ evalcommand(union node *cmd, int flags)
9677 listsetvar(varlist.list, VEXPORT|VSTACK); 9683 listsetvar(varlist.list, VEXPORT|VSTACK);
9678 shellexec(argv, path, cmdentry.u.index); 9684 shellexec(argv, path, cmdentry.u.index);
9679 /* NOTREACHED */ 9685 /* NOTREACHED */
9680 9686 } /* default */
9681 case CMDBUILTIN: 9687 case CMDBUILTIN:
9682 cmdenviron = varlist.list; 9688 cmdenviron = varlist.list;
9683 if (cmdenviron) { 9689 if (cmdenviron) {
@@ -9722,7 +9728,8 @@ evalcommand(union node *cmd, int flags)
9722 if (evalfun(cmdentry.u.func, argc, argv, flags)) 9728 if (evalfun(cmdentry.u.func, argc, argv, flags))
9723 goto raise; 9729 goto raise;
9724 break; 9730 break;
9725 } 9731
9732 } /* switch */
9726 9733
9727 out: 9734 out:
9728 popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec); 9735 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