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