]> git.sur5r.net Git - openldap/blob - libraries/liblutil/detach.c
1b7125b6ac8d52ba5077ebe378e5c721e0203102
[openldap] / libraries / liblutil / detach.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright (c) 1990, 1994 Regents of the University of Michigan.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms are permitted
11  * provided that this notice is preserved and that due credit is given
12  * to the University of Michigan at Ann Arbor. The name of the University
13  * may not be used to endorse or promote products derived from this
14  * software without specific prior written permission. This software
15  * is provided ``as is'' without express or implied warranty.
16  */
17
18 #include "portable.h"
19
20 #include <stdio.h>
21
22 #include <ac/stdlib.h>
23 #include <ac/signal.h>
24 #include <ac/socket.h>
25 #include <ac/unistd.h>
26
27 #include <sys/stat.h>
28 #include <fcntl.h>
29
30 #ifdef HAVE_SYS_FILE_H
31 #include <sys/file.h>
32 #endif
33 #ifdef HAVE_SYS_IOCTL_H
34 #include <sys/ioctl.h>
35 #endif
36
37 #include "lutil.h"
38
39 void
40 lutil_detach( int debug, int do_close )
41 {
42         int             i, sd, nbits;
43
44 #ifdef HAVE_SYSCONF
45         nbits = sysconf( _SC_OPEN_MAX );
46 #elif HAVE_GETDTABLESIZE
47         nbits = getdtablesize();
48 #else
49         nbits = FD_SETSIZE;
50 #endif
51
52 #ifdef FD_SETSIZE
53         if ( nbits > FD_SETSIZE ) {
54                 nbits = FD_SETSIZE;
55         }
56 #endif /* FD_SETSIZE */
57
58         if ( debug == 0 ) {
59                 for ( i = 0; i < 5; i++ ) {
60 #if HAVE_THR
61                         switch ( fork1() )
62 #else
63                         switch ( fork() )
64 #endif
65                         {
66                         case -1:
67                                 sleep( 5 );
68                                 continue;
69
70                         case 0:
71                                 break;
72
73                         default:
74                                 _exit( EXIT_SUCCESS );
75                         }
76                         break;
77                 }
78
79                 if ( (sd = open( "/dev/null", O_RDWR   )) == -1 &&
80                          (sd = open( "/dev/null", O_RDONLY )) == -1 &&
81                          /* Panic -- open *something* */
82                          (sd = open( "/",         O_RDONLY )) == -1    ) {
83                         perror("/dev/null");
84                 } else {
85                         /* redirect stdin, stdout, stderr to /dev/null */
86                         dup2( sd, STDIN_FILENO );
87                         dup2( sd, STDOUT_FILENO );
88                         dup2( sd, STDERR_FILENO );
89
90                         switch( sd ) {
91                         default:
92                                 close( sd );
93                         case STDIN_FILENO:
94                         case STDOUT_FILENO:
95                         case STDERR_FILENO:
96                                 break;
97                         }
98                 }
99
100                 if ( do_close ) {
101                         /* close everything else */
102                         for ( i = 0; i < nbits; i++ ) {
103                                 if( i != STDIN_FILENO &&
104                                         i != STDOUT_FILENO && 
105                                         i != STDERR_FILENO )
106                                 {
107                                         close( i );
108                                 }
109                         }
110                 }
111
112 #ifdef CHDIR_TO_ROOT
113                 (void) chdir( "/" );
114 #endif
115
116 #ifdef HAVE_SETSID
117                 (void) setsid();
118 #elif TIOCNOTTY
119                 if ( (sd = open( "/dev/tty", O_RDWR )) != -1 ) {
120                         (void) ioctl( sd, TIOCNOTTY, NULL );
121                         (void) close( sd );
122                 }
123 #endif
124         } 
125
126 #ifdef SIGPIPE
127         (void) SIGNAL( SIGPIPE, SIG_IGN );
128 #endif
129 }