NOMMU re-exec trick shuld not depend on existence of "don't daemonize"
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 24 Mar 2007 12:11:17 +0000 (12:11 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 24 Mar 2007 12:11:17 +0000 (12:11 -0000)
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.

applets/busybox.c
applets/individual.c
include/libbb.h
libbb/vfork_daemon_rexec.c
miscutils/crond.c
miscutils/watchdog.c
networking/dnsd.c
networking/inetd.c
sysklogd/klogd.c
sysklogd/syslogd.c

index 0387d79b7c9b968bcc49ae9a4c01dcc9bf5fcc3c..5334827ca7617b297f43a90639f12985c28aff90 100644 (file)
@@ -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++;
index 0721683525d540ed4185cf3a7cc0677a77fa2752..1667f188b73d4b70a12ab0f5f86f23886c1e6f59 100644 (file)
@@ -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);
 }
index 659bfcaa7cf1b19c03b8e1c2f60b9815d36d4c9d..0cfc220188e2ad0e965d3cdfa1e3a465d778eda5 100644 (file)
@@ -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[];
 
index 26d1826e015518b0e750ccb8d8a389accd5b39b6..3185f2d396d9dc5f14d6fd06606b9ea724ba2f3d 100644 (file)
 #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 */
index d237a677ed09d705f5e2887e98a9e6274e43e84e..1ab0038e0390951449b7379972934879803083e0 100644 (file)
@@ -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
index ed9026d9e449f31516fbb0c77a7170909e4c7227..e3d77d17eed165a4daeb069cf80f554d059a8fb3 100644 (file)
@@ -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);
index 78722d6f619c98a3e939b49ce009a5f3cf8af4ad..fb0c56cce70a56b169409f834780e3a6ffd779d3 100644 (file)
@@ -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
index 8016823c09c35983cd9d52ffd4630324cecaf7a3..48e23db2ea437211a6cb9f029bc4363b9475f9be 100644 (file)
@@ -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
index cca6f56711672e77f369283e533b0dcfd7a6b081..fc0ed303769ca835244de37b8c2e015c97d11e15 100644 (file)
@@ -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
index 2a2b20c8bc00da65272746a42ff8c62c0be685c6..437212372948361f7e5bb08e0a36d90c32c26451 100644 (file)
@@ -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