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 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