1 /* $NetBSD: detach.c,v 1.8 2021/08/14 16:14:58 christos 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-2021 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 <sys/cdefs.h> 34 __RCSID("$NetBSD: detach.c,v 1.8 2021/08/14 16:14:58 christos Exp $"); 35 36 #include "portable.h" 37 38 #include <stdio.h> 39 40 #include <ac/stdlib.h> 41 #include <ac/signal.h> 42 #include <ac/socket.h> 43 #include <ac/unistd.h> 44 45 #include <sys/stat.h> 46 #include <fcntl.h> 47 48 #ifdef HAVE_SYS_FILE_H 49 #include <sys/file.h> 50 #endif 51 #ifdef HAVE_SYS_IOCTL_H 52 #include <sys/ioctl.h> 53 #endif 54 55 #include "lutil.h" 56 57 int 58 lutil_detach( int debug, int do_close ) 59 { 60 int i, sd, nbits, pid; 61 62 #ifdef HAVE_SYSCONF 63 nbits = sysconf( _SC_OPEN_MAX ); 64 #elif defined(HAVE_GETDTABLESIZE) 65 nbits = getdtablesize(); 66 #else 67 nbits = FD_SETSIZE; 68 #endif 69 70 #ifdef FD_SETSIZE 71 if ( nbits > FD_SETSIZE ) { 72 nbits = FD_SETSIZE; 73 } 74 #endif /* FD_SETSIZE */ 75 76 if ( debug == 0 ) { 77 for ( i = 0; i < 5; i++ ) { 78 #ifdef HAVE_THR 79 pid = fork1(); 80 #else 81 pid = fork(); 82 #endif 83 switch ( pid ) 84 { 85 case -1: 86 sleep( 5 ); 87 continue; 88 89 case 0: 90 break; 91 92 default: 93 return pid; 94 } 95 break; 96 } 97 98 if ( (sd = open( "/dev/null", O_RDWR )) == -1 && 99 (sd = open( "/dev/null", O_RDONLY )) == -1 && 100 /* Panic -- open *something* */ 101 (sd = open( "/", O_RDONLY )) == -1 ) { 102 perror("/dev/null"); 103 } else { 104 /* redirect stdin, stdout, stderr to /dev/null */ 105 dup2( sd, STDIN_FILENO ); 106 dup2( sd, STDOUT_FILENO ); 107 dup2( sd, STDERR_FILENO ); 108 109 switch( sd ) { 110 default: 111 close( sd ); 112 case STDIN_FILENO: 113 case STDOUT_FILENO: 114 case STDERR_FILENO: 115 break; 116 } 117 } 118 119 if ( do_close ) { 120 /* close everything else */ 121 for ( i = 0; i < nbits; i++ ) { 122 if( i != STDIN_FILENO && 123 i != STDOUT_FILENO && 124 i != STDERR_FILENO ) 125 { 126 close( i ); 127 } 128 } 129 } 130 131 #ifdef CHDIR_TO_ROOT 132 (void) chdir( "/" ); 133 #endif 134 135 #ifdef HAVE_SETSID 136 (void) setsid(); 137 #elif defined(TIOCNOTTY) 138 if ( (sd = open( "/dev/tty", O_RDWR )) != -1 ) { 139 (void) ioctl( sd, TIOCNOTTY, NULL ); 140 (void) close( sd ); 141 } 142 #endif 143 } 144 145 #ifdef SIGPIPE 146 (void) SIGNAL( SIGPIPE, SIG_IGN ); 147 #endif 148 return 0; 149 } 150