Back to index

openldap  2.4.31
detach.c
Go to the documentation of this file.
00001 /* detach.c -- routines to daemonize a process */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 1998-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /*
00017  * Copyright (c) 1990, 1994 Regents of the University of Michigan.
00018  * All rights reserved.
00019  *
00020  * Redistribution and use in source and binary forms are permitted
00021  * provided that this notice is preserved and that due credit is given
00022  * to the University of Michigan at Ann Arbor. The name of the University
00023  * may not be used to endorse or promote products derived from this
00024  * software without specific prior written permission. This software
00025  * is provided ``as is'' without express or implied warranty.
00026  */
00027 /* This work was originally developed by the University of Michigan
00028  * and distributed as part of U-MICH LDAP.
00029  */
00030 
00031 #include "portable.h"
00032 
00033 #include <stdio.h>
00034 
00035 #include <ac/stdlib.h>
00036 #include <ac/signal.h>
00037 #include <ac/socket.h>
00038 #include <ac/unistd.h>
00039 
00040 #include <sys/stat.h>
00041 #include <fcntl.h>
00042 
00043 #ifdef HAVE_SYS_FILE_H
00044 #include <sys/file.h>
00045 #endif
00046 #ifdef HAVE_SYS_IOCTL_H
00047 #include <sys/ioctl.h>
00048 #endif
00049 
00050 #include "lutil.h"
00051 
00052 int
00053 lutil_detach( int debug, int do_close )
00054 {
00055        int           i, sd, nbits, pid;
00056 
00057 #ifdef HAVE_SYSCONF
00058        nbits = sysconf( _SC_OPEN_MAX );
00059 #elif defined(HAVE_GETDTABLESIZE)
00060        nbits = getdtablesize();
00061 #else
00062        nbits = FD_SETSIZE;
00063 #endif
00064 
00065 #ifdef FD_SETSIZE
00066        if ( nbits > FD_SETSIZE ) {
00067               nbits = FD_SETSIZE;
00068        }
00069 #endif /* FD_SETSIZE */
00070 
00071        if ( debug == 0 ) {
00072               for ( i = 0; i < 5; i++ ) {
00073 #ifdef HAVE_THR
00074                      pid = fork1();
00075 #else
00076                      pid = fork();
00077 #endif
00078                      switch ( pid )
00079                      {
00080                      case -1:
00081                             sleep( 5 );
00082                             continue;
00083 
00084                      case 0:
00085                             break;
00086 
00087                      default:
00088                             return pid;
00089                      }
00090                      break;
00091               }
00092 
00093               if ( (sd = open( "/dev/null", O_RDWR   )) == -1 &&
00094                       (sd = open( "/dev/null", O_RDONLY )) == -1 &&
00095                       /* Panic -- open *something* */
00096                       (sd = open( "/",         O_RDONLY )) == -1    ) {
00097                      perror("/dev/null");
00098               } else {
00099                      /* redirect stdin, stdout, stderr to /dev/null */
00100                      dup2( sd, STDIN_FILENO );
00101                      dup2( sd, STDOUT_FILENO );
00102                      dup2( sd, STDERR_FILENO );
00103 
00104                      switch( sd ) {
00105                      default:
00106                             close( sd );
00107                      case STDIN_FILENO:
00108                      case STDOUT_FILENO:
00109                      case STDERR_FILENO:
00110                             break;
00111                      }
00112               }
00113 
00114               if ( do_close ) {
00115                      /* close everything else */
00116                      for ( i = 0; i < nbits; i++ ) {
00117                             if( i != STDIN_FILENO &&
00118                                    i != STDOUT_FILENO && 
00119                                    i != STDERR_FILENO )
00120                             {
00121                                    close( i );
00122                             }
00123                      }
00124               }
00125 
00126 #ifdef CHDIR_TO_ROOT
00127               (void) chdir( "/" );
00128 #endif
00129 
00130 #ifdef HAVE_SETSID
00131               (void) setsid();
00132 #elif defined(TIOCNOTTY)
00133               if ( (sd = open( "/dev/tty", O_RDWR )) != -1 ) {
00134                      (void) ioctl( sd, TIOCNOTTY, NULL );
00135                      (void) close( sd );
00136               }
00137 #endif
00138        } 
00139 
00140 #ifdef SIGPIPE
00141        (void) SIGNAL( SIGPIPE, SIG_IGN );
00142 #endif
00143        return 0;
00144 }