xref: /titanic_44/usr/src/lib/libc/port/gen/daemon.c (revision 44991a1c1bb35cccb6bf99cb6dce14864dcee19c)
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