1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1990, 1993 The Regents of the University of California.
5 * Copyright (c) 2017 Mariusz Zaborski <[email protected]>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __SCCSID("@(#)daemon.c 8.1 (Berkeley) 6/4/93");
35 __FBSDID("$FreeBSD$");
36
37 #include "namespace.h"
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <paths.h>
41 #include <stdlib.h>
42 #include <signal.h>
43 #include <unistd.h>
44 #include "un-namespace.h"
45 #include "libc_private.h"
46
47 int
daemonfd(int chdirfd,int nullfd)48 daemonfd(int chdirfd, int nullfd)
49 {
50 struct sigaction osa, sa;
51 pid_t newgrp;
52 int oerrno;
53 int osa_ok;
54
55 /* A SIGHUP may be thrown when the parent exits below. */
56 sigemptyset(&sa.sa_mask);
57 sa.sa_handler = SIG_IGN;
58 sa.sa_flags = 0;
59 osa_ok = __libc_sigaction(SIGHUP, &sa, &osa);
60
61 switch (fork()) {
62 case -1:
63 return (-1);
64 case 0:
65 break;
66 default:
67 /*
68 * A fine point: _exit(0), not exit(0), to avoid triggering
69 * atexit(3) processing
70 */
71 _exit(0);
72 }
73
74 newgrp = setsid();
75 oerrno = errno;
76 if (osa_ok != -1)
77 __libc_sigaction(SIGHUP, &osa, NULL);
78
79 if (newgrp == -1) {
80 errno = oerrno;
81 return (-1);
82 }
83
84 if (chdirfd != -1)
85 (void)fchdir(chdirfd);
86
87 if (nullfd != -1) {
88 (void)_dup2(nullfd, STDIN_FILENO);
89 (void)_dup2(nullfd, STDOUT_FILENO);
90 (void)_dup2(nullfd, STDERR_FILENO);
91 }
92 return (0);
93 }
94
95 int
daemon(int nochdir,int noclose)96 daemon(int nochdir, int noclose)
97 {
98 int chdirfd, nullfd, ret;
99
100 if (!noclose)
101 nullfd = _open(_PATH_DEVNULL, O_RDWR, 0);
102 else
103 nullfd = -1;
104
105 if (!nochdir)
106 chdirfd = _open("/", O_EXEC);
107 else
108 chdirfd = -1;
109
110 ret = daemonfd(chdirfd, nullfd);
111
112 if (chdirfd != -1)
113 _close(chdirfd);
114
115 if (nullfd > 2)
116 _close(nullfd);
117
118 return (ret);
119 }
120