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 | ; |
