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