diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-09-14 11:48:28 +1000 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-09-14 11:48:28 +1000 |
commit | adcaaebedad72991d917fc57348a1b7a87067c2d (patch) | |
tree | e3b65813eca78851ac8a723bc3ac972faa43a475 | |
parent | 743d85e7d1c2a721baf020b9d79f45f0df2420a9 (diff) | |
parent | 42c4b2e3b535314ae8a7b65c3223afb26872d5a2 (diff) | |
download | busybox-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.c | 23 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_leak.right | 1 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_leak.tests | 7 |
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 @@ | |||
1 | should be empty: '' | 1 | should be empty: '' |
2 | should be empty: '' | ||
2 | should be not empty: 'val2' | 3 | should be not empty: 'val2' |
3 | should be not empty: 'val3' | 4 | should 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 |
3 | VAR='' | 3 | VAR='' |
4 | VAR=val0 cat /dev/null | ||
5 | echo "should be empty: '$VAR'" | ||
6 | |||
7 | # true is a regular builtin, variable should not leak out of it. | ||
8 | VAR='' | ||
4 | VAR=val1 true | 9 | VAR=val1 true |
5 | echo "should be empty: '$VAR'" | 10 | echo "should be empty: '$VAR'" |
6 | 11 | ||