NOMMU re-exec trick shuld not depend on existence of "don't daemonize"
[oweals/busybox.git] / libbb / vfork_daemon_rexec.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Rexec program for system have fork() as vfork() with foreground option
4  *
5  * Copyright (C) Vladimir N. Oleynik <dzo@simtreas.ru>
6  * Copyright (C) 2003 Russ Dill <Russ.Dill@asu.edu>
7  *
8  * daemon() portion taken from uClibc:
9  *
10  * Copyright (c) 1991, 1993
11  *      The Regents of the University of California.  All rights reserved.
12  *
13  * Modified for uClibc by Erik Andersen <andersee@debian.org>
14  *
15  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
16  */
17
18 #include <paths.h>
19 #include "libbb.h"
20
21 #ifdef BB_NOMMU
22 void vfork_daemon_rexec(int nochdir, int noclose, char **argv)
23 {
24         int fd;
25
26         setsid();
27
28         if (!nochdir)
29                 xchdir("/");
30
31         if (!noclose) {
32                 /* if "/dev/null" doesn't exist, bail out! */
33                 fd = xopen(bb_dev_null, O_RDWR);
34                 dup2(fd, STDIN_FILENO);
35                 dup2(fd, STDOUT_FILENO);
36                 dup2(fd, STDERR_FILENO);
37                 while (fd > 2)
38                         close(fd--);
39         }
40
41         switch (vfork()) {
42         case 0: /* child */
43                 /* Make certain we are not a session leader, or else we
44                  * might reacquire a controlling terminal */
45                 if (vfork())
46                         _exit(0);
47                 /* High-order bit of first char in argv[0] is a hidden
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);
52         case -1: /* error */
53                 bb_perror_msg_and_die("vfork");
54         default: /* parent */
55                 exit(0);
56         }
57 }
58 #endif /* BB_NOMMU */