1 /* $NetBSD: detach.c,v 1.3 2014/05/28 10:12:43 tron Exp $ */ 2 3 /* detach.c -- routines to daemonize a process */ 4 /* $OpenLDAP$ */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2014 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 /* 19 * Copyright (c) 1990, 1994 Regents of the University of Michigan. 20 * All rights reserved. 21 * 22 * Redistribution and use in source and binary forms are permitted 23 * provided that this notice is preserved and that due credit is given 24 * to the University of Michigan at Ann Arbor. The name of the University 25 * may not be used to endorse or promote products derived from this 26 * software without specific prior written permission. This software 27 * is provided ``as is'' without express or implied warranty. 28 */ 29 /* This work was originally developed by the University of Michigan 30 * and distributed as part of U-MICH LDAP. 31 */ 32 33 #include "portable.h" 34 35 #include <stdio.h> 36 37 #include <ac/stdlib.h> 38 #include <ac/signal.h> 39 #include <ac/socket.h> 40 #include <ac/unistd.h> 41 42 #include <sys/stat.h> 43 #include <fcntl.h> 44 45 #ifdef HAVE_SYS_FILE_H 46 #include <sys/file.h> 47 #endif 48 #ifdef HAVE_SYS_IOCTL_H 49 #include <sys/ioctl.h> 50 #endif 51 52 #include "lutil.h" 53 54 int 55 lutil_detach( int debug, int do_close ) 56 { 57 int i, sd, nbits, pid; 58 59 #ifdef HAVE_SYSCONF 60 nbits = sysconf( _SC_OPEN_MAX ); 61 #elif defined(HAVE_GETDTABLESIZE) 62 nbits = getdtablesize(); 63 #else 64 nbits = FD_SETSIZE; 65 #endif 66 67 #ifdef FD_SETSIZE 68 if ( nbits > FD_SETSIZE ) { 69 nbits = FD_SETSIZE; 70 } 71 #endif /* FD_SETSIZE */ 72 73 if ( debug == 0 ) { 74 for ( i = 0; i < 5; i++ ) { 75 #ifdef HAVE_THR 76 pid = fork1(); 77 #else 78 pid = fork(); 79 #endif 80 switch ( pid ) 81 { 82 case -1: 83 sleep( 5 ); 84 continue; 85 86 case 0: 87 break; 88 89 default: 90 return pid; 91 } 92 break; 93 } 94 95 if ( (sd = open( "/dev/null", O_RDWR )) == -1 && 96 (sd = open( "/dev/null", O_RDONLY )) == -1 && 97 /* Panic -- open *something* */ 98 (sd = open( "/", O_RDONLY )) == -1 ) { 99 perror("/dev/null"); 100 } else { 101 /* redirect stdin, stdout, stderr to /dev/null */ 102 dup2( sd, STDIN_FILENO ); 103 dup2( sd, STDOUT_FILENO ); 104 dup2( sd, STDERR_FILENO ); 105 106 switch( sd ) { 107 default: 108 close( sd ); 109 case STDIN_FILENO: 110 case STDOUT_FILENO: 111 case STDERR_FILENO: 112 break; 113 } 114 } 115 116 if ( do_close ) { 117 /* close everything else */ 118 for ( i = 0; i < nbits; i++ ) { 119 if( i != STDIN_FILENO && 120 i != STDOUT_FILENO && 121 i != STDERR_FILENO ) 122 { 123 close( i ); 124 } 125 } 126 } 127 128 #ifdef CHDIR_TO_ROOT 129 (void) chdir( "/" ); 130 #endif 131 132 #ifdef HAVE_SETSID 133 (void) setsid(); 134 #elif defined(TIOCNOTTY) 135 if ( (sd = open( "/dev/tty", O_RDWR )) != -1 ) { 136 (void) ioctl( sd, TIOCNOTTY, NULL ); 137 (void) close( sd ); 138 } 139 #endif 140 } 141 142 #ifdef SIGPIPE 143 (void) SIGNAL( SIGPIPE, SIG_IGN ); 144 #endif 145 return 0; 146 } 147