blob: 81ae1268718ada056ddd8d085e4780a022237c61 [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
Russ Dilla1fece22003-12-15 21:57:44 +000018#include <paths.h>
Eric Andersen35e643b2003-07-28 07:40:39 +000019#include "libbb.h"
20
Bernhard Reutner-Fischerc418d482006-05-31 10:19:51 +000021#ifdef BB_NOMMU
Rob Landleyd9a761d2006-06-16 16:35:53 +000022void vfork_daemon_rexec(int nochdir, int noclose,
23 int argc, char **argv, char *foreground_opt)
Eric Andersen35e643b2003-07-28 07:40:39 +000024{
Russ Dilla1fece22003-12-15 21:57:44 +000025 int fd;
Rob Landleyd9a761d2006-06-16 16:35:53 +000026 char **vfork_args;
27 int a = 0;
Eric Andersenc7bda1c2004-03-15 08:29:22 +000028
Russ Dilla1fece22003-12-15 21:57:44 +000029 setsid();
Eric Andersenc7bda1c2004-03-15 08:29:22 +000030
Russ Dilla1fece22003-12-15 21:57:44 +000031 if (!nochdir)
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +000032 xchdir("/");
Russ Dilla1fece22003-12-15 21:57:44 +000033
Bernhard Reutner-Fischer0a8812b2006-05-19 13:12:21 +000034 if (!noclose && (fd = open(bb_dev_null, O_RDWR, 0)) != -1) {
Russ Dilla1fece22003-12-15 21:57:44 +000035 dup2(fd, STDIN_FILENO);
36 dup2(fd, STDOUT_FILENO);
37 dup2(fd, STDERR_FILENO);
38 if (fd > 2)
39 close(fd);
Rob Landleyd9a761d2006-06-16 16:35:53 +000040 }
Eric Andersen35e643b2003-07-28 07:40:39 +000041
Denis Vlasenkobf0a2012006-12-26 10:42:51 +000042 vfork_args = xzalloc(sizeof(char *) * (argc + 3));
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +000043 vfork_args[a++] = CONFIG_BUSYBOX_EXEC_PATH;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +000044 while (*argv) {
Denis Vlasenko55a99402006-09-30 20:41:44 +000045 vfork_args[a++] = *argv;
46 argv++;
Eric Andersen35e643b2003-07-28 07:40:39 +000047 }
48 vfork_args[a] = foreground_opt;
Russ Dilla1fece22003-12-15 21:57:44 +000049 switch (vfork()) {
50 case 0: /* child */
51 /* Make certain we are not a session leader, or else we
52 * might reacquire a controlling terminal */
53 if (vfork())
54 _exit(0);
55 execv(vfork_args[0], vfork_args);
56 bb_perror_msg_and_die("execv %s", vfork_args[0]);
57 case -1: /* error */
58 bb_perror_msg_and_die("vfork");
59 default: /* parent */
60 exit(0);
Eric Andersenc7bda1c2004-03-15 08:29:22 +000061 }
Eric Andersen35e643b2003-07-28 07:40:39 +000062}
Bernhard Reutner-Fischerc418d482006-05-31 10:19:51 +000063#endif /* BB_NOMMU */