summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko2007-03-24 12:11:17 +0000
committerDenis Vlasenko2007-03-24 12:11:17 +0000
commit9067f13be067f39f6c8586926b190b7dee0def3d (patch)
treeff0a10f5f81fa0e1e719691c147309a9cc9bef46
parent1b6fa4c57ced2ae89f51bdc073410c4be5384007 (diff)
downloadbusybox-9067f13be067f39f6c8586926b190b7dee0def3d.zip
busybox-9067f13be067f39f6c8586926b190b7dee0def3d.tar.gz
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.c7
-rw-r--r--applets/individual.c3
-rw-r--r--include/libbb.h5
-rw-r--r--libbb/vfork_daemon_rexec.c23
-rw-r--r--miscutils/crond.c4
-rw-r--r--miscutils/watchdog.c8
-rw-r--r--networking/dnsd.c4
-rw-r--r--networking/inetd.c4
-rw-r--r--sysklogd/klogd.c3
-rw-r--r--sysklogd/syslogd.c3
10 files changed, 34 insertions, 30 deletions
diff --git a/applets/busybox.c b/applets/busybox.c
index 0387d79..5334827 100644
--- a/applets/busybox.c
+++ b/applets/busybox.c
@@ -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++;
diff --git a/applets/individual.c b/applets/individual.c
index 0721683..1667f18 100644
--- a/applets/individual.c
+++ b/applets/individual.c
@@ -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);
}
diff --git a/include/libbb.h b/include/libbb.h
index 659bfca..0cfc220 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 *
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[];
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index 26d1826..3185f2d 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -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 */
diff --git a/miscutils/crond.c b/miscutils/crond.c
index d237a67..1ab0038 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -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
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index ed9026d..e3d77d1 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -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);
diff --git a/networking/dnsd.c b/networking/dnsd.c
index 78722d6..fb0c56c 100644
--- a/networking/dnsd.c
+++ b/networking/dnsd.c
@@ -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
diff --git a/networking/inetd.c b/networking/inetd.c
index 8016823..48e23db 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -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
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index cca6f56..fc0ed30 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -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
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 2a2b20c..4372123 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -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