1 /* $NetBSD: detach.c,v 1.2 2011/06/20 09:11:17 mrg Exp $ */ 2 3 /* detach.c -- routines to daemonize a process */ 4 /* OpenLDAP: pkg/ldap/libraries/liblutil/detach.c,v 1.18.2.5 2010/04/13 20:23:05 kurt Exp */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2010 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 void 55 lutil_detach( int debug, int do_close ) 56 { 57 int i, sd, nbits; 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 switch ( fork1() ) 77 #else 78 switch ( fork() ) 79 #endif 80 { 81 case -1: 82 sleep( 5 ); 83 continue; 84 85 case 0: 86 break; 87 88 default: 89 _exit( EXIT_SUCCESS ); 90 } 91 break; 92 } 93 94 if ( (sd = open( "/dev/null", O_RDWR )) == -1 && 95 (sd = open( "/dev/null", O_RDONLY )) == -1 && 96 /* Panic -- open *something* */ 97 (sd = open( "/", O_RDONLY )) == -1 ) { 98 perror("/dev/null"); 99 } else { 100 /* redirect stdin, stdout, stderr to /dev/null */ 101 dup2( sd, STDIN_FILENO ); 102 dup2( sd, STDOUT_FILENO ); 103 dup2( sd, STDERR_FILENO ); 104 105 switch( sd ) { 106 default: 107 close( sd ); 108 case STDIN_FILENO: 109 case STDOUT_FILENO: 110 case STDERR_FILENO: 111 break; 112 } 113 } 114 115 if ( do_close ) { 116 /* close everything else */ 117 for ( i = 0; i < nbits; i++ ) { 118 if( i != STDIN_FILENO && 119 i != STDOUT_FILENO && 120 i != STDERR_FILENO ) 121 { 122 close( i ); 123 } 124 } 125 } 126 127 #ifdef CHDIR_TO_ROOT 128 (void) chdir( "/" ); 129 #endif 130 131 #ifdef HAVE_SETSID 132 (void) setsid(); 133 #elif defined(TIOCNOTTY) 134 if ( (sd = open( "/dev/tty", O_RDWR )) != -1 ) { 135 (void) ioctl( sd, TIOCNOTTY, NULL ); 136 (void) close( sd ); 137 } 138 #endif 139 } 140 141 #ifdef SIGPIPE 142 (void) SIGNAL( SIGPIPE, SIG_IGN ); 143 #endif 144 } 145