1*44991a1cSVladimir Kotal /*
2*44991a1cSVladimir Kotal * CDDL HEADER START
3*44991a1cSVladimir Kotal *
4*44991a1cSVladimir Kotal * The contents of this file are subject to the terms of the
5*44991a1cSVladimir Kotal * Common Development and Distribution License (the "License").
6*44991a1cSVladimir Kotal * You may not use this file except in compliance with the License.
7*44991a1cSVladimir Kotal *
8*44991a1cSVladimir Kotal * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*44991a1cSVladimir Kotal * or http://www.opensolaris.org/os/licensing.
10*44991a1cSVladimir Kotal * See the License for the specific language governing permissions
11*44991a1cSVladimir Kotal * and limitations under the License.
12*44991a1cSVladimir Kotal *
13*44991a1cSVladimir Kotal * When distributing Covered Code, include this CDDL HEADER in each
14*44991a1cSVladimir Kotal * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*44991a1cSVladimir Kotal * If applicable, add the following below this CDDL HEADER, with the
16*44991a1cSVladimir Kotal * fields enclosed by brackets "[]" replaced with your own identifying
17*44991a1cSVladimir Kotal * information: Portions Copyright [yyyy] [name of copyright owner]
18*44991a1cSVladimir Kotal *
19*44991a1cSVladimir Kotal * CDDL HEADER END
20*44991a1cSVladimir Kotal */
21*44991a1cSVladimir Kotal
22*44991a1cSVladimir Kotal /*
23*44991a1cSVladimir Kotal * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*44991a1cSVladimir Kotal * Use is subject to license terms.
25*44991a1cSVladimir Kotal */
26*44991a1cSVladimir Kotal
27*44991a1cSVladimir Kotal #include "lint.h"
28*44991a1cSVladimir Kotal #include "file64.h"
29*44991a1cSVladimir Kotal #include "mtlib.h"
30*44991a1cSVladimir Kotal
31*44991a1cSVladimir Kotal #include <stdio.h>
32*44991a1cSVladimir Kotal #include <stdlib.h>
33*44991a1cSVladimir Kotal #include <unistd.h>
34*44991a1cSVladimir Kotal #include <fcntl.h>
35*44991a1cSVladimir Kotal
36*44991a1cSVladimir Kotal #include "stdiom.h"
37*44991a1cSVladimir Kotal
38*44991a1cSVladimir Kotal /*
39*44991a1cSVladimir Kotal * Use fork/setsid/fork to go into background and permanently remove
40*44991a1cSVladimir Kotal * controlling terminal.
41*44991a1cSVladimir Kotal */
42*44991a1cSVladimir Kotal int
daemon(int nochdir,int noclose)43*44991a1cSVladimir Kotal daemon(int nochdir, int noclose)
44*44991a1cSVladimir Kotal {
45*44991a1cSVladimir Kotal int retv, fd;
46*44991a1cSVladimir Kotal
47*44991a1cSVladimir Kotal /*
48*44991a1cSVladimir Kotal * By the first fork+setsid, we disconnect from our current controlling
49*44991a1cSVladimir Kotal * terminal and become a session group leader.
50*44991a1cSVladimir Kotal */
51*44991a1cSVladimir Kotal retv = fork();
52*44991a1cSVladimir Kotal if (retv == -1)
53*44991a1cSVladimir Kotal return (-1);
54*44991a1cSVladimir Kotal if (retv != 0)
55*44991a1cSVladimir Kotal _exit(EXIT_SUCCESS);
56*44991a1cSVladimir Kotal if (setsid() == -1)
57*44991a1cSVladimir Kotal return (-1);
58*44991a1cSVladimir Kotal /*
59*44991a1cSVladimir Kotal * By forking again without calling setsid again, we make certain
60*44991a1cSVladimir Kotal * that we are not the session group leader and can never reacquire
61*44991a1cSVladimir Kotal * a controlling terminal.
62*44991a1cSVladimir Kotal */
63*44991a1cSVladimir Kotal retv = fork();
64*44991a1cSVladimir Kotal if (retv == -1)
65*44991a1cSVladimir Kotal return (-1);
66*44991a1cSVladimir Kotal if (retv != 0)
67*44991a1cSVladimir Kotal _exit(EXIT_SUCCESS);
68*44991a1cSVladimir Kotal
69*44991a1cSVladimir Kotal if (nochdir == 0)
70*44991a1cSVladimir Kotal (void) chdir("/");
71*44991a1cSVladimir Kotal
72*44991a1cSVladimir Kotal if (noclose == 0) {
73*44991a1cSVladimir Kotal /*
74*44991a1cSVladimir Kotal * Missing the PRIV_FILE_READ privilege may be one of the
75*44991a1cSVladimir Kotal * reasons that prevent the opening of /dev/null to succeed.
76*44991a1cSVladimir Kotal */
77*44991a1cSVladimir Kotal if ((fd = open("/dev/null", O_RDWR)) == -1)
78*44991a1cSVladimir Kotal return (-1);
79*44991a1cSVladimir Kotal
80*44991a1cSVladimir Kotal /*
81*44991a1cSVladimir Kotal * Also, if any of the descriptor redirects fails we should
82*44991a1cSVladimir Kotal * return with error to signal to the caller that his request
83*44991a1cSVladimir Kotal * cannot be fulfilled properly. It is up to the caller to
84*44991a1cSVladimir Kotal * do the cleanup.
85*44991a1cSVladimir Kotal */
86*44991a1cSVladimir Kotal if ((fd != STDIN_FILENO) && (dup2(fd, STDIN_FILENO) < 0)) {
87*44991a1cSVladimir Kotal (void) close(fd);
88*44991a1cSVladimir Kotal return (-1);
89*44991a1cSVladimir Kotal }
90*44991a1cSVladimir Kotal if ((fd != STDOUT_FILENO) && (dup2(fd, STDOUT_FILENO) < 0)) {
91*44991a1cSVladimir Kotal (void) close(fd);
92*44991a1cSVladimir Kotal return (-1);
93*44991a1cSVladimir Kotal }
94*44991a1cSVladimir Kotal if ((fd != STDERR_FILENO) && (dup2(fd, STDERR_FILENO) < 0)) {
95*44991a1cSVladimir Kotal (void) close(fd);
96*44991a1cSVladimir Kotal return (-1);
97*44991a1cSVladimir Kotal }
98*44991a1cSVladimir Kotal
99*44991a1cSVladimir Kotal if (fd > STDERR_FILENO)
100*44991a1cSVladimir Kotal (void) close(fd);
101*44991a1cSVladimir Kotal }
102*44991a1cSVladimir Kotal return (0);
103*44991a1cSVladimir Kotal }
104