blob: 7e4b0c09703b1195aa758a02de4a230b96f9cd1b [file] [log] [blame]
Bernhard Reutner-Fischer0a8812b2006-05-19 13:12:21 +00001/* vi: set sw=4 ts=4: */
Eric Andersen35e643b2003-07-28 07:40:39 +00002/*
Eric Andersenaff114c2004-04-14 17:51:38 +00003 * Rexec program for system have fork() as vfork() with foreground option
Russ Dilla1fece22003-12-15 21:57:44 +00004 *
5 * Copyright (C) Vladimir N. Oleynik <dzo@simtreas.ru>
6 * Copyright (C) 2003 Russ Dill <Russ.Dill@asu.edu>
7 *
Eric Andersenaff114c2004-04-14 17:51:38 +00008 * daemon() portion taken from uClibc:
Russ Dilla1fece22003-12-15 21:57:44 +00009 *
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 *
Bernhard Reutner-Fischer0a8812b2006-05-19 13:12:21 +000015 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Eric Andersen35e643b2003-07-28 07:40:39 +000016 */
17
18#include <unistd.h>
Russ Dilla1fece22003-12-15 21:57:44 +000019#include <stdio.h>
20#include <fcntl.h>
21#include <paths.h>
Eric Andersen35e643b2003-07-28 07:40:39 +000022#include "libbb.h"
23
24
Bernhard Reutner-Fischerc418d482006-05-31 10:19:51 +000025#ifdef BB_NOMMU
Rob Landleyd9a761d2006-06-16 16:35:53 +000026void vfork_daemon_rexec(int nochdir, int noclose,
27 int argc, char **argv, char *foreground_opt)
Eric Andersen35e643b2003-07-28 07:40:39 +000028{
Russ Dilla1fece22003-12-15 21:57:44 +000029 int fd;
Rob Landleyd9a761d2006-06-16 16:35:53 +000030 char **vfork_args;
31 int a = 0;
Eric Andersenc7bda1c2004-03-15 08:29:22 +000032
Russ Dilla1fece22003-12-15 21:57:44 +000033 setsid();
Eric Andersenc7bda1c2004-03-15 08:29:22 +000034
Russ Dilla1fece22003-12-15 21:57:44 +000035 if (!nochdir)
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +000036 xchdir("/");
Russ Dilla1fece22003-12-15 21:57:44 +000037
Bernhard Reutner-Fischer0a8812b2006-05-19 13:12:21 +000038 if (!noclose && (fd = open(bb_dev_null, O_RDWR, 0)) != -1) {
Russ Dilla1fece22003-12-15 21:57:44 +000039 dup2(fd, STDIN_FILENO);
40 dup2(fd, STDOUT_FILENO);
41 dup2(fd, STDERR_FILENO);
42 if (fd > 2)
43 close(fd);
Rob Landleyd9a761d2006-06-16 16:35:53 +000044 }
Eric Andersen35e643b2003-07-28 07:40:39 +000045
46 vfork_args = xcalloc(sizeof(char *), argc + 3);
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +000047 vfork_args[a++] = CONFIG_BUSYBOX_EXEC_PATH;
Eric Andersen35e643b2003-07-28 07:40:39 +000048 while(*argv) {
49 vfork_args[a++] = *argv;
50 argv++;
51 }
52 vfork_args[a] = foreground_opt;
Russ Dilla1fece22003-12-15 21:57:44 +000053 switch (vfork()) {
54 case 0: /* child */
55 /* Make certain we are not a session leader, or else we
56 * might reacquire a controlling terminal */
57 if (vfork())
58 _exit(0);
59 execv(vfork_args[0], vfork_args);
60 bb_perror_msg_and_die("execv %s", vfork_args[0]);
61 case -1: /* error */
62 bb_perror_msg_and_die("vfork");
63 default: /* parent */
64 exit(0);
Eric Andersenc7bda1c2004-03-15 08:29:22 +000065 }
Eric Andersen35e643b2003-07-28 07:40:39 +000066}
Bernhard Reutner-Fischerc418d482006-05-31 10:19:51 +000067#endif /* BB_NOMMU */