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