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.
#include "busybox.h"
const char *applet_name ATTRIBUTE_EXTERNALLY_VISIBLE;
+smallint re_execed;
#ifdef CONFIG_FEATURE_INSTALLER
/*
{
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++;
#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);
}
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);
};
#define FILEUTILS_CP_OPTSTR "pdRfils" USE_SELINUX("c")
+extern smallint re_execed;
extern const char *applet_name;
extern const char BB_BANNER[];
#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);
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 */
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
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);
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
#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
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
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