xref: /illumos-gate/usr/src/lib/libc/port/gen/daemon.c (revision 48bbca81)
144991a1cSVladimir Kotal /*
244991a1cSVladimir Kotal  * CDDL HEADER START
344991a1cSVladimir Kotal  *
444991a1cSVladimir Kotal  * The contents of this file are subject to the terms of the
544991a1cSVladimir Kotal  * Common Development and Distribution License (the "License").
644991a1cSVladimir Kotal  * You may not use this file except in compliance with the License.
744991a1cSVladimir Kotal  *
844991a1cSVladimir Kotal  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
944991a1cSVladimir Kotal  * or http://www.opensolaris.org/os/licensing.
1044991a1cSVladimir Kotal  * See the License for the specific language governing permissions
1144991a1cSVladimir Kotal  * and limitations under the License.
1244991a1cSVladimir Kotal  *
1344991a1cSVladimir Kotal  * When distributing Covered Code, include this CDDL HEADER in each
1444991a1cSVladimir Kotal  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1544991a1cSVladimir Kotal  * If applicable, add the following below this CDDL HEADER, with the
1644991a1cSVladimir Kotal  * fields enclosed by brackets "[]" replaced with your own identifying
1744991a1cSVladimir Kotal  * information: Portions Copyright [yyyy] [name of copyright owner]
1844991a1cSVladimir Kotal  *
1944991a1cSVladimir Kotal  * CDDL HEADER END
2044991a1cSVladimir Kotal  */
2144991a1cSVladimir Kotal 
2244991a1cSVladimir Kotal /*
2344991a1cSVladimir Kotal  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2444991a1cSVladimir Kotal  * Use is subject to license terms.
25*48bbca81SDaniel Hoffman  * Copyright (c) 2016 by Delphix. All rights reserved.
2644991a1cSVladimir Kotal  */
2744991a1cSVladimir Kotal 
2844991a1cSVladimir Kotal #include "lint.h"
2944991a1cSVladimir Kotal #include "file64.h"
3044991a1cSVladimir Kotal #include "mtlib.h"
3144991a1cSVladimir Kotal 
3244991a1cSVladimir Kotal #include <stdio.h>
3344991a1cSVladimir Kotal #include <stdlib.h>
3444991a1cSVladimir Kotal #include <unistd.h>
3544991a1cSVladimir Kotal #include <fcntl.h>
3644991a1cSVladimir Kotal 
3744991a1cSVladimir Kotal #include "stdiom.h"
3844991a1cSVladimir Kotal 
3944991a1cSVladimir Kotal /*
4044991a1cSVladimir Kotal  * Use fork/setsid/fork to go into background and permanently remove
4144991a1cSVladimir Kotal  * controlling terminal.
4244991a1cSVladimir Kotal  */
4344991a1cSVladimir Kotal int
daemon(int nochdir,int noclose)4444991a1cSVladimir Kotal daemon(int nochdir, int noclose)
4544991a1cSVladimir Kotal {
4644991a1cSVladimir Kotal 	int retv, fd;
4744991a1cSVladimir Kotal 
4844991a1cSVladimir Kotal 	/*
4944991a1cSVladimir Kotal 	 * By the first fork+setsid, we disconnect from our current controlling
5044991a1cSVladimir Kotal 	 * terminal and become a session group leader.
5144991a1cSVladimir Kotal 	 */
5244991a1cSVladimir Kotal 	retv = fork();
5344991a1cSVladimir Kotal 	if (retv == -1)
5444991a1cSVladimir Kotal 		return (-1);
5544991a1cSVladimir Kotal 	if (retv != 0)
5644991a1cSVladimir Kotal 		_exit(EXIT_SUCCESS);
5744991a1cSVladimir Kotal 	if (setsid() == -1)
5844991a1cSVladimir Kotal 		return (-1);
5944991a1cSVladimir Kotal 	/*
6044991a1cSVladimir Kotal 	 * By forking again without calling setsid again, we make certain
6144991a1cSVladimir Kotal 	 * that we are not the session group leader and can never reacquire
6244991a1cSVladimir Kotal 	 * a controlling terminal.
6344991a1cSVladimir Kotal 	 */
6444991a1cSVladimir Kotal 	retv = fork();
6544991a1cSVladimir Kotal 	if (retv == -1)
6644991a1cSVladimir Kotal 		return (-1);
6744991a1cSVladimir Kotal 	if (retv != 0)
6844991a1cSVladimir Kotal 		_exit(EXIT_SUCCESS);
6944991a1cSVladimir Kotal 
7044991a1cSVladimir Kotal 	if (nochdir == 0)
7144991a1cSVladimir Kotal 		(void) chdir("/");
7244991a1cSVladimir Kotal 
7344991a1cSVladimir Kotal 	if (noclose == 0) {
7444991a1cSVladimir Kotal 		/*
7544991a1cSVladimir Kotal 		 * Missing the PRIV_FILE_READ privilege may be one of the
7644991a1cSVladimir Kotal 		 * reasons that prevent the opening of /dev/null to succeed.
7744991a1cSVladimir Kotal 		 */
7844991a1cSVladimir Kotal 		if ((fd = open("/dev/null", O_RDWR)) == -1)
7944991a1cSVladimir Kotal 			return (-1);
8044991a1cSVladimir Kotal 
8144991a1cSVladimir Kotal 		/*
8244991a1cSVladimir Kotal 		 * Also, if any of the descriptor redirects fails we should
83*48bbca81SDaniel Hoffman 		 * return with error to signal to the caller that its request
8444991a1cSVladimir Kotal 		 * cannot be fulfilled properly. It is up to the caller to
8544991a1cSVladimir Kotal 		 * do the cleanup.
8644991a1cSVladimir Kotal 		 */
8744991a1cSVladimir Kotal 		if ((fd != STDIN_FILENO) && (dup2(fd, STDIN_FILENO) < 0)) {
8844991a1cSVladimir Kotal 			(void) close(fd);
8944991a1cSVladimir Kotal 			return (-1);
9044991a1cSVladimir Kotal 		}
9144991a1cSVladimir Kotal 		if ((fd != STDOUT_FILENO) && (dup2(fd, STDOUT_FILENO) < 0)) {
9244991a1cSVladimir Kotal 			(void) close(fd);
9344991a1cSVladimir Kotal 			return (-1);
9444991a1cSVladimir Kotal 		}
9544991a1cSVladimir Kotal 		if ((fd != STDERR_FILENO) && (dup2(fd, STDERR_FILENO) < 0)) {
9644991a1cSVladimir Kotal 			(void) close(fd);
9744991a1cSVladimir Kotal 			return (-1);
9844991a1cSVladimir Kotal 		}
9944991a1cSVladimir Kotal 
10044991a1cSVladimir Kotal 		if (fd > STDERR_FILENO)
10144991a1cSVladimir Kotal 			(void) close(fd);
10244991a1cSVladimir Kotal 	}
10344991a1cSVladimir Kotal 	return (0);
10444991a1cSVladimir Kotal }
105