00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * wvfork() just runs fork(), but it closes all file descriptors that are 00006 * flagged close-on-exec, since we don't necessarily always run exec() 00007 * after we fork()... 00008 * 00009 * This fixes the year-old mystery bug where WvTapeBackup caused watchdog 00010 * reboots because the CHILD process wasn't touching it, and it was already 00011 * open before the fork()... 00012 * 00013 * If you want to explicitly leave a file descriptor OPEN, even if it's 00014 * marked close-on-exec, then add the fd number to dontclose, and pass that 00015 * to wvfork(). This is mainly useful for WvLoopbacks -- you may want 00016 * certain ones open or closed depending on which call to wvfork() you're 00017 * making. (for WvTapeBackup, you want the three backup loopbacks open, 00018 * and, say, any WvResolver loopbacks closed.) 00019 */ 00020 00021 #include <fcntl.h> 00022 00023 #include "wvfork.h" 00024 00025 #define MAX_FD 256 // FIXME: is this enough? 00026 00027 pid_t wvfork( int dontclose1, int dontclose2 ) 00028 /********************************************/ 00029 { 00030 WvIntTable t( 1 ); 00031 if( dontclose1 >= 0 ) 00032 t.add( &dontclose1, false ); 00033 if( dontclose2 >= 0 ) 00034 t.add( &dontclose2, false ); 00035 return( wvfork( t ) ); 00036 } 00037 00038 pid_t wvfork( WvIntTable& dontclose ) 00039 /***********************************/ 00040 { 00041 pid_t pid = fork(); 00042 00043 if( pid != 0 ) { 00044 // parent process, or error 00045 return( pid ); 00046 } 00047 00048 // child process 00049 // check the close-on-exec flag of all file descriptors 00050 for( int fd=0; fd<MAX_FD; fd++ ) { 00051 if( !dontclose[ fd ] && ( fcntl( fd, F_GETFD ) & FD_CLOEXEC ) > 0 ) 00052 close( fd ); 00053 } 00054 return( pid ); 00055 } 00056