diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-24 12:11:17 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-24 12:11:17 +0000 |
commit | 9067f13be067f39f6c8586926b190b7dee0def3d (patch) | |
tree | ff0a10f5f81fa0e1e719691c147309a9cc9bef46 | |
parent | 1b6fa4c57ced2ae89f51bdc073410c4be5384007 (diff) | |
download | busybox-w32-9067f13be067f39f6c8586926b190b7dee0def3d.tar.gz busybox-w32-9067f13be067f39f6c8586926b190b7dee0def3d.tar.bz2 busybox-w32-9067f13be067f39f6c8586926b190b7dee0def3d.zip |
NOMMU re-exec trick shuld not depend on existence of "don't daemonize"
option for every affected applet (and dnsd, for example, don't have one).
Thus rework re-exec support to not require it. Code got smaller too.
-rw-r--r-- | applets/busybox.c | 7 | ||||
-rw-r--r-- | applets/individual.c | 3 | ||||
-rw-r--r-- | include/libbb.h | 5 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 23 | ||||
-rw-r--r-- | miscutils/crond.c | 4 | ||||
-rw-r--r-- | miscutils/watchdog.c | 8 | ||||
-rw-r--r-- | networking/dnsd.c | 4 | ||||
-rw-r--r-- | networking/inetd.c | 4 | ||||
-rw-r--r-- | sysklogd/klogd.c | 3 | ||||
-rw-r--r-- | sysklogd/syslogd.c | 3 |
10 files changed, 34 insertions, 30 deletions
diff --git a/applets/busybox.c b/applets/busybox.c index 0387d79b7..5334827ca 100644 --- a/applets/busybox.c +++ b/applets/busybox.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "busybox.h" | 7 | #include "busybox.h" |
8 | 8 | ||
9 | const char *applet_name ATTRIBUTE_EXTERNALLY_VISIBLE; | 9 | const char *applet_name ATTRIBUTE_EXTERNALLY_VISIBLE; |
10 | smallint re_execed; | ||
10 | 11 | ||
11 | #ifdef CONFIG_FEATURE_INSTALLER | 12 | #ifdef CONFIG_FEATURE_INSTALLER |
12 | /* | 13 | /* |
@@ -59,6 +60,12 @@ int main(int argc, char **argv) | |||
59 | { | 60 | { |
60 | const char *s; | 61 | const char *s; |
61 | 62 | ||
63 | /* NOMMU re-exec trick sets high-order bit in first byte of name */ | ||
64 | if (argv[0][0] & 0x80) { | ||
65 | re_execed = 1; | ||
66 | argv[0][0] &= 0x7f; | ||
67 | } | ||
68 | |||
62 | applet_name = argv[0]; | 69 | applet_name = argv[0]; |
63 | if (*applet_name == '-') | 70 | if (*applet_name == '-') |
64 | applet_name++; | 71 | applet_name++; |
diff --git a/applets/individual.c b/applets/individual.c index 072168352..1667f188b 100644 --- a/applets/individual.c +++ b/applets/individual.c | |||
@@ -9,12 +9,11 @@ const char *applet_name; | |||
9 | 9 | ||
10 | #include <stdio.h> | 10 | #include <stdio.h> |
11 | #include <stdlib.h> | 11 | #include <stdlib.h> |
12 | //Ok to remove? #include "bb_config.h" | ||
13 | #include "usage.h" | 12 | #include "usage.h" |
14 | 13 | ||
15 | int main(int argc, char *argv[]) | 14 | int main(int argc, char *argv[]) |
16 | { | 15 | { |
17 | applet_name=argv[0]; | 16 | applet_name = argv[0]; |
18 | 17 | ||
19 | return APPLET_main(argc,argv); | 18 | return APPLET_main(argc,argv); |
20 | } | 19 | } |
diff --git a/include/libbb.h b/include/libbb.h index 659bfcaa7..0cfc22018 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -616,9 +616,7 @@ extern int index_in_substr_array(const char * const string_array[], const char * | |||
616 | extern void print_login_issue(const char *issue_file, const char *tty); | 616 | extern void print_login_issue(const char *issue_file, const char *tty); |
617 | extern void print_login_prompt(void); | 617 | extern void print_login_prompt(void); |
618 | #ifdef BB_NOMMU | 618 | #ifdef BB_NOMMU |
619 | extern void vfork_daemon(int nochdir, int noclose); | 619 | extern void vfork_daemon_rexec(int nochdir, int noclose, char **argv); |
620 | extern void vfork_daemon_rexec(int nochdir, int noclose, | ||
621 | int argc, char **argv, char *foreground_opt); | ||
622 | #endif | 620 | #endif |
623 | extern int get_terminal_width_height(const int fd, int *width, int *height); | 621 | extern int get_terminal_width_height(const int fd, int *width, int *height); |
624 | 622 | ||
@@ -763,6 +761,7 @@ enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */ | |||
763 | }; | 761 | }; |
764 | 762 | ||
765 | #define FILEUTILS_CP_OPTSTR "pdRfils" USE_SELINUX("c") | 763 | #define FILEUTILS_CP_OPTSTR "pdRfils" USE_SELINUX("c") |
764 | extern smallint re_execed; | ||
766 | extern const char *applet_name; | 765 | extern const char *applet_name; |
767 | extern const char BB_BANNER[]; | 766 | extern const char BB_BANNER[]; |
768 | 767 | ||
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 26d1826e0..3185f2d39 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -19,19 +19,18 @@ | |||
19 | #include "libbb.h" | 19 | #include "libbb.h" |
20 | 20 | ||
21 | #ifdef BB_NOMMU | 21 | #ifdef BB_NOMMU |
22 | void vfork_daemon_rexec(int nochdir, int noclose, | 22 | void vfork_daemon_rexec(int nochdir, int noclose, char **argv) |
23 | int argc, char **argv, char *foreground_opt) | ||
24 | { | 23 | { |
25 | int fd; | 24 | int fd; |
26 | char **vfork_args; | ||
27 | int a = 0; | ||
28 | 25 | ||
29 | setsid(); | 26 | setsid(); |
30 | 27 | ||
31 | if (!nochdir) | 28 | if (!nochdir) |
32 | xchdir("/"); | 29 | xchdir("/"); |
33 | 30 | ||
34 | if (!noclose && (fd = open(bb_dev_null, O_RDWR, 0)) != -1) { | 31 | if (!noclose) { |
32 | /* if "/dev/null" doesn't exist, bail out! */ | ||
33 | fd = xopen(bb_dev_null, O_RDWR); | ||
35 | dup2(fd, STDIN_FILENO); | 34 | dup2(fd, STDIN_FILENO); |
36 | dup2(fd, STDOUT_FILENO); | 35 | dup2(fd, STDOUT_FILENO); |
37 | dup2(fd, STDERR_FILENO); | 36 | dup2(fd, STDERR_FILENO); |
@@ -39,21 +38,17 @@ void vfork_daemon_rexec(int nochdir, int noclose, | |||
39 | close(fd--); | 38 | close(fd--); |
40 | } | 39 | } |
41 | 40 | ||
42 | vfork_args = xzalloc(sizeof(char *) * (argc + 3)); | ||
43 | vfork_args[a++] = CONFIG_BUSYBOX_EXEC_PATH; | ||
44 | while (*argv) { | ||
45 | vfork_args[a++] = *argv; | ||
46 | argv++; | ||
47 | } | ||
48 | vfork_args[a] = foreground_opt; | ||
49 | switch (vfork()) { | 41 | switch (vfork()) { |
50 | case 0: /* child */ | 42 | case 0: /* child */ |
51 | /* Make certain we are not a session leader, or else we | 43 | /* Make certain we are not a session leader, or else we |
52 | * might reacquire a controlling terminal */ | 44 | * might reacquire a controlling terminal */ |
53 | if (vfork()) | 45 | if (vfork()) |
54 | _exit(0); | 46 | _exit(0); |
55 | execv(vfork_args[0], vfork_args); | 47 | /* High-order bit of first char in argv[0] is a hidden |
56 | bb_perror_msg_and_die("execv %s", vfork_args[0]); | 48 | * "we have (alrealy) re-execed, don't do it again" flag */ |
49 | argv[0][0] |= 0x80; | ||
50 | execv(CONFIG_BUSYBOX_EXEC_PATH, argv); | ||
51 | bb_perror_msg_and_die("exec %s", CONFIG_BUSYBOX_EXEC_PATH); | ||
57 | case -1: /* error */ | 52 | case -1: /* error */ |
58 | bb_perror_msg_and_die("vfork"); | 53 | bb_perror_msg_and_die("vfork"); |
59 | default: /* parent */ | 54 | default: /* parent */ |
diff --git a/miscutils/crond.c b/miscutils/crond.c index d237a677e..1ab0038e0 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
@@ -191,8 +191,8 @@ int crond_main(int ac, char **av) | |||
191 | 191 | ||
192 | if (!(opt & 4)) { | 192 | if (!(opt & 4)) { |
193 | #ifdef BB_NOMMU | 193 | #ifdef BB_NOMMU |
194 | /* reexec for vfork() do continue parent */ | 194 | if (!re_execed) |
195 | vfork_daemon_rexec(1, 0, ac, av, "-f"); | 195 | vfork_daemon_rexec(1, 0, av); |
196 | #else | 196 | #else |
197 | xdaemon(1, 0); | 197 | xdaemon(1, 0); |
198 | #endif | 198 | #endif |
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c index ed9026d9e..e3d77d17e 100644 --- a/miscutils/watchdog.c +++ b/miscutils/watchdog.c | |||
@@ -38,12 +38,14 @@ int watchdog_main(int argc, char **argv) | |||
38 | if (optind < argc - 1 || argc == 1) | 38 | if (optind < argc - 1 || argc == 1) |
39 | bb_show_usage(); | 39 | bb_show_usage(); |
40 | 40 | ||
41 | if (!(opts & OPT_FOREGROUND)) { | ||
41 | #ifdef BB_NOMMU | 42 | #ifdef BB_NOMMU |
42 | if (!(opts & OPT_FOREGROUND)) | 43 | if (!re_execed) |
43 | vfork_daemon_rexec(0, 1, argc, argv, "-F"); | 44 | vfork_daemon_rexec(0, 1, argv); |
44 | #else | 45 | #else |
45 | xdaemon(0, 1); | 46 | xdaemon(0, 1); |
46 | #endif | 47 | #endif |
48 | } | ||
47 | 49 | ||
48 | signal(SIGHUP, watchdog_shutdown); | 50 | signal(SIGHUP, watchdog_shutdown); |
49 | signal(SIGINT, watchdog_shutdown); | 51 | signal(SIGINT, watchdog_shutdown); |
diff --git a/networking/dnsd.c b/networking/dnsd.c index 78722d6f6..fb0c56cce 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c | |||
@@ -357,8 +357,8 @@ int dnsd_main(int argc, char **argv) | |||
357 | if (OPT_daemon) { | 357 | if (OPT_daemon) { |
358 | //FIXME: NOMMU will NOT set LOGMODE_SYSLOG! | 358 | //FIXME: NOMMU will NOT set LOGMODE_SYSLOG! |
359 | #ifdef BB_NOMMU | 359 | #ifdef BB_NOMMU |
360 | /* reexec for vfork() do continue parent */ | 360 | if (!re_execed) |
361 | vfork_daemon_rexec(1, 0, argc, argv, "-d"); | 361 | vfork_daemon_rexec(1, 0, argv); |
362 | #else | 362 | #else |
363 | xdaemon(1, 0); | 363 | xdaemon(1, 0); |
364 | #endif | 364 | #endif |
diff --git a/networking/inetd.c b/networking/inetd.c index 8016823c0..48e23db2e 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -1289,8 +1289,8 @@ int inetd_main(int argc, char *argv[]) | |||
1289 | 1289 | ||
1290 | #ifdef BB_NOMMU | 1290 | #ifdef BB_NOMMU |
1291 | if (!(opt & 2)) { | 1291 | if (!(opt & 2)) { |
1292 | /* reexec for vfork() do continue parent */ | 1292 | if (!re_execed) |
1293 | vfork_daemon_rexec(0, 0, argc, argv, "-f"); | 1293 | vfork_daemon_rexec(0, 0, argv); |
1294 | } | 1294 | } |
1295 | bb_sanitize_stdio(); | 1295 | bb_sanitize_stdio(); |
1296 | #else | 1296 | #else |
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index cca6f5671..fc0ed3037 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c | |||
@@ -51,7 +51,8 @@ int klogd_main(int argc, char **argv) | |||
51 | 51 | ||
52 | if (!(option_mask32 & OPT_FOREGROUND)) { | 52 | if (!(option_mask32 & OPT_FOREGROUND)) { |
53 | #ifdef BB_NOMMU | 53 | #ifdef BB_NOMMU |
54 | vfork_daemon_rexec(0, 1, argc, argv, "-n"); | 54 | if (!re_execed) |
55 | vfork_daemon_rexec(0, 1, argv); | ||
55 | #else | 56 | #else |
56 | bb_daemonize(); | 57 | bb_daemonize(); |
57 | #endif | 58 | #endif |
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 2a2b20c8b..437212372 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -643,7 +643,8 @@ int syslogd_main(int argc, char **argv) | |||
643 | 643 | ||
644 | if (!(option_mask32 & OPT_nofork)) { | 644 | if (!(option_mask32 & OPT_nofork)) { |
645 | #ifdef BB_NOMMU | 645 | #ifdef BB_NOMMU |
646 | vfork_daemon_rexec(0, 1, argc, argv, "-n"); | 646 | if (!re_execed) |
647 | vfork_daemon_rexec(0, 1, argv); | ||
647 | #else | 648 | #else |
648 | bb_daemonize(); | 649 | bb_daemonize(); |
649 | #endif | 650 | #endif |