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