diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-01-21 00:41:04 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-01-21 00:41:04 +0000 |
commit | bb21944ea0d5e95f07691dfaeaba404ddfa70528 (patch) | |
tree | 3e82c2dd94d674a723f3d7df350f32dc8892adc1 | |
parent | ff978c7d73d84e06ee5dc927a180cdc794d35b21 (diff) | |
download | busybox-w32-bb21944ea0d5e95f07691dfaeaba404ddfa70528.tar.gz busybox-w32-bb21944ea0d5e95f07691dfaeaba404ddfa70528.tar.bz2 busybox-w32-bb21944ea0d5e95f07691dfaeaba404ddfa70528.zip |
Introduce FEATURE_EXEC_PREFER_APPLETS = "re-execute our own
executable if we asked to exec someting with argv[0] == known_applet"
Use it in init. Also respect PATH in init, remove explicit "/sbin" etc
from exec. Patch by Gabriel L. Somlo <somlo@cmu.edu>
git-svn-id: svn://busybox.net/trunk/busybox@17426 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | Config.in | 10 | ||||
-rw-r--r-- | init/init.c | 29 | ||||
-rw-r--r-- | libbb/xfuncs.c | 7 | ||||
-rw-r--r-- | scripts/defconfig | 1 | ||||
-rw-r--r-- | shell/ash.c | 4 |
5 files changed, 39 insertions, 12 deletions
@@ -231,6 +231,14 @@ config SELINUX | |||
231 | 231 | ||
232 | Most people will leave this set to 'N'. | 232 | Most people will leave this set to 'N'. |
233 | 233 | ||
234 | config FEATURE_EXEC_PREFER_APPLETS | ||
235 | bool "exec prefers applets" | ||
236 | default n | ||
237 | help | ||
238 | This is an experimental option which directs applets about to | ||
239 | call 'exec' to try and find an applicable busybox applet before | ||
240 | searching the executable path for a binary or symlink to execute. | ||
241 | |||
234 | config BUSYBOX_EXEC_PATH | 242 | config BUSYBOX_EXEC_PATH |
235 | string "Path to BusyBox executable" | 243 | string "Path to BusyBox executable" |
236 | default "/proc/self/exe" | 244 | default "/proc/self/exe" |
@@ -439,7 +447,7 @@ config INSTALL_APPLET_HARDLINKS | |||
439 | config INSTALL_APPLET_DONT | 447 | config INSTALL_APPLET_DONT |
440 | bool | 448 | bool |
441 | prompt "not installed" | 449 | prompt "not installed" |
442 | depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE_SHELL | 450 | depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE_SHELL || FEATURE_EXEC_PREFER_APPLETS |
443 | help | 451 | help |
444 | Do not install applet links. Useful when using the -install feature | 452 | Do not install applet links. Useful when using the -install feature |
445 | or a standalone shell for rescue pruposes. | 453 | or a standalone shell for rescue pruposes. |
diff --git a/init/init.c b/init/init.c index 6fc68afb1..7694b4448 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -389,6 +389,7 @@ static pid_t run(const struct init_action *a) | |||
389 | #include CUSTOMIZED_BANNER | 389 | #include CUSTOMIZED_BANNER |
390 | #endif | 390 | #endif |
391 | "\nPlease press Enter to activate this console. "; | 391 | "\nPlease press Enter to activate this console. "; |
392 | char *prog; | ||
392 | 393 | ||
393 | /* Block sigchild while forking. */ | 394 | /* Block sigchild while forking. */ |
394 | sigemptyset(&nmask); | 395 | sigemptyset(&nmask); |
@@ -560,7 +561,10 @@ static pid_t run(const struct init_action *a) | |||
560 | 561 | ||
561 | /* Now run it. The new program will take over this PID, | 562 | /* Now run it. The new program will take over this PID, |
562 | * so nothing further in init.c should be run. */ | 563 | * so nothing further in init.c should be run. */ |
563 | execv(cmdpath, cmd); | 564 | prog = cmdpath; |
565 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog)) | ||
566 | prog = CONFIG_BUSYBOX_EXEC_PATH; | ||
567 | execvp(prog, cmd); | ||
564 | 568 | ||
565 | /* We're still here? Some error happened. */ | 569 | /* We're still here? Some error happened. */ |
566 | message(LOG | CONSOLE, "Bummer, cannot run '%s': %m", cmdpath); | 570 | message(LOG | CONSOLE, "Bummer, cannot run '%s': %m", cmdpath); |
@@ -678,6 +682,7 @@ static void exec_signal(int sig ATTRIBUTE_UNUSED) | |||
678 | { | 682 | { |
679 | struct init_action *a, *tmp; | 683 | struct init_action *a, *tmp; |
680 | sigset_t unblock_signals; | 684 | sigset_t unblock_signals; |
685 | char *prog; | ||
681 | 686 | ||
682 | for (a = init_action_list; a; a = tmp) { | 687 | for (a = init_action_list; a; a = tmp) { |
683 | tmp = a->next; | 688 | tmp = a->next; |
@@ -713,7 +718,10 @@ static void exec_signal(int sig ATTRIBUTE_UNUSED) | |||
713 | dup(0); | 718 | dup(0); |
714 | 719 | ||
715 | messageD(CONSOLE | LOG, "Trying to re-exec %s", a->command); | 720 | messageD(CONSOLE | LOG, "Trying to re-exec %s", a->command); |
716 | execl(a->command, a->command, NULL); | 721 | prog = a->command; |
722 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog)) | ||
723 | prog = CONFIG_BUSYBOX_EXEC_PATH; | ||
724 | execlp(prog, a->command, NULL); | ||
717 | 725 | ||
718 | message(CONSOLE | LOG, "exec of '%s' failed: %m", | 726 | message(CONSOLE | LOG, "exec of '%s' failed: %m", |
719 | a->command); | 727 | a->command); |
@@ -852,13 +860,13 @@ static void parse_inittab(void) | |||
852 | /* No inittab file -- set up some default behavior */ | 860 | /* No inittab file -- set up some default behavior */ |
853 | #endif | 861 | #endif |
854 | /* Reboot on Ctrl-Alt-Del */ | 862 | /* Reboot on Ctrl-Alt-Del */ |
855 | new_init_action(CTRLALTDEL, "/sbin/reboot", ""); | 863 | new_init_action(CTRLALTDEL, "reboot", ""); |
856 | /* Umount all filesystems on halt/reboot */ | 864 | /* Umount all filesystems on halt/reboot */ |
857 | new_init_action(SHUTDOWN, "/bin/umount -a -r", ""); | 865 | new_init_action(SHUTDOWN, "umount -a -r", ""); |
858 | /* Swapoff on halt/reboot */ | 866 | /* Swapoff on halt/reboot */ |
859 | if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "/sbin/swapoff -a", ""); | 867 | if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", ""); |
860 | /* Prepare to restart init when a HUP is received */ | 868 | /* Prepare to restart init when a HUP is received */ |
861 | new_init_action(RESTART, "/sbin/init", ""); | 869 | new_init_action(RESTART, "init", ""); |
862 | /* Askfirst shell on tty1-4 */ | 870 | /* Askfirst shell on tty1-4 */ |
863 | new_init_action(ASKFIRST, bb_default_login_shell, ""); | 871 | new_init_action(ASKFIRST, bb_default_login_shell, ""); |
864 | new_init_action(ASKFIRST, bb_default_login_shell, VC_2); | 872 | new_init_action(ASKFIRST, bb_default_login_shell, VC_2); |
@@ -1039,9 +1047,9 @@ int init_main(int argc, char **argv) | |||
1039 | { | 1047 | { |
1040 | message(CONSOLE,"Low memory: forcing swapon."); | 1048 | message(CONSOLE,"Low memory: forcing swapon."); |
1041 | /* swapon -a requires /proc typically */ | 1049 | /* swapon -a requires /proc typically */ |
1042 | new_init_action(SYSINIT, "/bin/mount -t proc proc /proc", ""); | 1050 | new_init_action(SYSINIT, "mount -t proc proc /proc", ""); |
1043 | /* Try to turn on swap */ | 1051 | /* Try to turn on swap */ |
1044 | new_init_action(SYSINIT, "/sbin/swapon -a", ""); | 1052 | new_init_action(SYSINIT, "swapon -a", ""); |
1045 | run_actions(SYSINIT); /* wait and removing */ | 1053 | run_actions(SYSINIT); /* wait and removing */ |
1046 | } | 1054 | } |
1047 | } | 1055 | } |
@@ -1068,7 +1076,10 @@ int init_main(int argc, char **argv) | |||
1068 | 1076 | ||
1069 | putenv("SELINUX_INIT=YES"); | 1077 | putenv("SELINUX_INIT=YES"); |
1070 | if (selinux_init_load_policy(&enforce) == 0) { | 1078 | if (selinux_init_load_policy(&enforce) == 0) { |
1071 | execv(argv[0], argv); | 1079 | char *prog = argv[0]; |
1080 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog)) | ||
1081 | prog = CONFIG_BUSYBOX_EXEC_PATH; | ||
1082 | execvp(prog, argv); | ||
1072 | } else if (enforce > 0) { | 1083 | } else if (enforce > 0) { |
1073 | /* SELinux in enforcing mode but load_policy failed */ | 1084 | /* SELinux in enforcing mode but load_policy failed */ |
1074 | /* At this point, we probably can't open /dev/console, so log() won't work */ | 1085 | /* At this point, we probably can't open /dev/console, so log() won't work */ |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 240ac5d3d..4252e7646 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -183,14 +183,17 @@ pid_t spawn(char **argv) | |||
183 | /* Why static? */ | 183 | /* Why static? */ |
184 | static int failed; | 184 | static int failed; |
185 | pid_t pid; | 185 | pid_t pid; |
186 | void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0; | 186 | char *prog; |
187 | 187 | ||
188 | // Be nice to nommu machines. | 188 | // Be nice to nommu machines. |
189 | failed = 0; | 189 | failed = 0; |
190 | pid = vfork(); | 190 | pid = vfork(); |
191 | if (pid < 0) return pid; | 191 | if (pid < 0) return pid; |
192 | if (!pid) { | 192 | if (!pid) { |
193 | execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv); | 193 | prog = argv[0]; |
194 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog)) | ||
195 | prog = CONFIG_BUSYBOX_EXEC_PATH; | ||
196 | execvp(prog, argv); | ||
194 | 197 | ||
195 | // We're sharing a stack with blocked parent, let parent know we failed | 198 | // We're sharing a stack with blocked parent, let parent know we failed |
196 | // and then exit to unblock parent (but don't run atexit() stuff, which | 199 | // and then exit to unblock parent (but don't run atexit() stuff, which |
diff --git a/scripts/defconfig b/scripts/defconfig index 2c82ed474..fc43deb2d 100644 --- a/scripts/defconfig +++ b/scripts/defconfig | |||
@@ -27,6 +27,7 @@ CONFIG_FEATURE_SYSLOG=y | |||
27 | CONFIG_FEATURE_SUID_CONFIG=y | 27 | CONFIG_FEATURE_SUID_CONFIG=y |
28 | CONFIG_FEATURE_SUID_CONFIG_QUIET=y | 28 | CONFIG_FEATURE_SUID_CONFIG_QUIET=y |
29 | # CONFIG_SELINUX is not set | 29 | # CONFIG_SELINUX is not set |
30 | #CONFIG_FEATURE_EXEC_PREFER_APPLETS is not set | ||
30 | CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" | 31 | CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" |
31 | 32 | ||
32 | # | 33 | # |
diff --git a/shell/ash.c b/shell/ash.c index 8ef8c465c..2db3302c7 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6528,6 +6528,10 @@ setjobctl(int on) | |||
6528 | int ofd; | 6528 | int ofd; |
6529 | ofd = fd = open(_PATH_TTY, O_RDWR); | 6529 | ofd = fd = open(_PATH_TTY, O_RDWR); |
6530 | if (fd < 0) { | 6530 | if (fd < 0) { |
6531 | /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails. | ||
6532 | * That sometimes helps to acquire controlling tty. | ||
6533 | * Obviously, a workaround for bugs when someone | ||
6534 | * failed to provide a controlling tty to bash! :) */ | ||
6531 | fd += 3; | 6535 | fd += 3; |
6532 | while (!isatty(fd) && --fd >= 0) | 6536 | while (!isatty(fd) && --fd >= 0) |
6533 | ; | 6537 | ; |