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.
No binary (build failed)
—
(log yok)
| @@ -7,6 +7,7 @@ | |
| #include "busybox.h" | |
| const char *applet_name ATTRIBUTE_EXTERNALLY_VISIBLE; | |
| + | smallint re_execed; |
| #ifdef CONFIG_FEATURE_INSTALLER | |
| /* | |
| @@ -59,6 +60,12 @@ int main(int argc, char **argv) | |
| { | |
| const char *s; | |
| + | /* NOMMU re-exec trick sets high-order bit in first byte of name */ |
| + | if (argv[0][0] & 0x80) { |
| + | re_execed = 1; |
| + | argv[0][0] &= 0x7f; |
| + | } |
| + | |
| applet_name = argv[0]; | |
| if (*applet_name == '-') | |
| applet_name++; | |
| @@ -9,12 +9,11 @@ const char *applet_name; | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| - | //Ok to remove? #include "bb_config.h" |
| #include "usage.h" | |
| int main(int argc, char *argv[]) | |
| { | |
| - | applet_name=argv[0]; |
| + | applet_name = argv[0]; |
| return APPLET_main(argc,argv); | |
| } | |
| @@ -616,9 +616,7 @@ extern int index_in_substr_array(const char * const string_array[], const char * | |
| extern void print_login_issue(const char *issue_file, const char *tty); | |
| extern void print_login_prompt(void); | |
| #ifdef BB_NOMMU | |
| - | extern void vfork_daemon(int nochdir, int noclose); |
| - | extern void vfork_daemon_rexec(int nochdir, int noclose, |
| - | int argc, char **argv, char *foreground_opt); |
| + | extern void vfork_daemon_rexec(int nochdir, int noclose, char **argv); |
| #endif | |
| extern int get_terminal_width_height(const int fd, int *width, int *height); | |
| @@ -763,6 +761,7 @@ enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */ | |
| }; | |
| #define FILEUTILS_CP_OPTSTR "pdRfils" USE_SELINUX("c") | |
| + | extern smallint re_execed; |
| extern const char *applet_name; | |
| extern const char BB_BANNER[]; | |
| @@ -19,19 +19,18 @@ | |
| #include "libbb.h" | |
| #ifdef BB_NOMMU | |
| - | void vfork_daemon_rexec(int nochdir, int noclose, |
| - | int argc, char **argv, char *foreground_opt) |
| + | void vfork_daemon_rexec(int nochdir, int noclose, char **argv) |
| { | |
| int fd; | |
| - | char **vfork_args; |
| - | int a = 0; |
| setsid(); | |
| if (!nochdir) | |
| xchdir("/"); | |
| - | if (!noclose && (fd = open(bb_dev_null, O_RDWR, 0)) != -1) { |
| + | if (!noclose) { |
| + | /* if "/dev/null" doesn't exist, bail out! */ |
| + | fd = xopen(bb_dev_null, O_RDWR); |
| dup2(fd, STDIN_FILENO); | |
| dup2(fd, STDOUT_FILENO); | |
| dup2(fd, STDERR_FILENO); | |
| @@ -39,21 +38,17 @@ void vfork_daemon_rexec(int nochdir, int noclose, | |
| close(fd--); | |
| } | |
| - | vfork_args = xzalloc(sizeof(char *) * (argc + 3)); |
| - | vfork_args[a++] = CONFIG_BUSYBOX_EXEC_PATH; |
| - | while (*argv) { |
| - | vfork_args[a++] = *argv; |
| - | argv++; |
| - | } |
| - | vfork_args[a] = foreground_opt; |
| switch (vfork()) { | |
| case 0: /* child */ | |
| /* Make certain we are not a session leader, or else we | |
| * might reacquire a controlling terminal */ | |
| if (vfork()) | |
| _exit(0); | |
| - | execv(vfork_args[0], vfork_args); |
| - | bb_perror_msg_and_die("execv %s", vfork_args[0]); |
| + | /* High-order bit of first char in argv[0] is a hidden |
| + | * "we have (alrealy) re-execed, don't do it again" flag */ |
| + | argv[0][0] |= 0x80; |
| + | execv(CONFIG_BUSYBOX_EXEC_PATH, argv); |
| + | bb_perror_msg_and_die("exec %s", CONFIG_BUSYBOX_EXEC_PATH); |
| case -1: /* error */ | |
| bb_perror_msg_and_die("vfork"); | |
| default: /* parent */ | |
| @@ -191,8 +191,8 @@ int crond_main(int ac, char **av) | |
| if (!(opt & 4)) { | |
| #ifdef BB_NOMMU | |
| - | /* reexec for vfork() do continue parent */ |
| - | vfork_daemon_rexec(1, 0, ac, av, "-f"); |
| + | if (!re_execed) |
| + | vfork_daemon_rexec(1, 0, av); |
| #else | |
| xdaemon(1, 0); | |
| #endif | |
| @@ -38,12 +38,14 @@ int watchdog_main(int argc, char **argv) | |
| if (optind < argc - 1 || argc == 1) | |
| bb_show_usage(); | |
| + | if (!(opts & OPT_FOREGROUND)) { |
| #ifdef BB_NOMMU | |
| - | if (!(opts & OPT_FOREGROUND)) |
| - | vfork_daemon_rexec(0, 1, argc, argv, "-F"); |
| + | if (!re_execed) |
| + | vfork_daemon_rexec(0, 1, argv); |
| #else | |
| - | xdaemon(0, 1); |
| + | xdaemon(0, 1); |
| #endif | |
| + | } |
| signal(SIGHUP, watchdog_shutdown); | |
| signal(SIGINT, watchdog_shutdown); | |
| @@ -357,8 +357,8 @@ int dnsd_main(int argc, char **argv) | |
| if (OPT_daemon) { | |
| //FIXME: NOMMU will NOT set LOGMODE_SYSLOG! | |
| #ifdef BB_NOMMU | |
| - | /* reexec for vfork() do continue parent */ |
| - | vfork_daemon_rexec(1, 0, argc, argv, "-d"); |
| + | if (!re_execed) |
| + | vfork_daemon_rexec(1, 0, argv); |
| #else | |
| xdaemon(1, 0); | |
| #endif | |
| @@ -1289,8 +1289,8 @@ int inetd_main(int argc, char *argv[]) | |
| #ifdef BB_NOMMU | |
| if (!(opt & 2)) { | |
| - | /* reexec for vfork() do continue parent */ |
| - | vfork_daemon_rexec(0, 0, argc, argv, "-f"); |
| + | if (!re_execed) |
| + | vfork_daemon_rexec(0, 0, argv); |
| } | |
| bb_sanitize_stdio(); | |
| #else | |
| @@ -51,7 +51,8 @@ int klogd_main(int argc, char **argv) | |
| if (!(option_mask32 & OPT_FOREGROUND)) { | |
| #ifdef BB_NOMMU | |
| - | vfork_daemon_rexec(0, 1, argc, argv, "-n"); |
| + | if (!re_execed) |
| + | vfork_daemon_rexec(0, 1, argv); |
| #else | |
| bb_daemonize(); | |
| #endif | |
| @@ -643,7 +643,8 @@ int syslogd_main(int argc, char **argv) | |
| if (!(option_mask32 & OPT_nofork)) { | |
| #ifdef BB_NOMMU | |
| - | vfork_daemon_rexec(0, 1, argc, argv, "-n"); |
| + | if (!re_execed) |
| + | vfork_daemon_rexec(0, 1, argv); |
| #else | |
| bb_daemonize(); | |
| #endif | |