00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <fcntl.h>
00022
00023
#include "wvfork.h"
00024
#include "wvlinklist.h"
00025
00026 #define MAX_FD sysconf(_SC_OPEN_MAX) + 1
00027
00028
DeclareWvList(
WvForkCallback);
00029 WvForkCallbackList
callbacks;
00030
00031
00032 void add_wvfork_callback(
WvForkCallback cb)
00033 {
00034
#if 0
00035
00036 WvForkCallbackList::Iter i(
callbacks);
00037
for (i.rewind(); i.next(); )
00038
if (*i == cb)
return;
00039
#endif
00040
callbacks.append(
new WvForkCallback(cb),
true);
00041 }
00042
00043
#if 0
00044
void remove_wvfork_callback(
WvForkCallback cb)
00045 {
00046 WvForkCallbackList::Iter i(callbacks);
00047
for (i.rewind(); i.next(); )
00048
if (*i == cb) i.xunlink();
00049 }
00050
#endif
00051
00052 pid_t
wvfork(
int dontclose1,
int dontclose2)
00053 {
00054 intTable t(1);
00055
if (dontclose1 >= 0)
00056 t.add(&dontclose1,
false);
00057
if (dontclose2 >= 0)
00058 t.add(&dontclose2,
false);
00059
return (
wvfork(t));
00060 }
00061
00062 pid_t
wvfork_start(
int *waitfd)
00063 {
00064
int waitpipe[2];
00065
00066
if (pipe(waitpipe) < 0)
00067
return -1;
00068
00069 pid_t pid = fork();
00070
00071 WvForkCallbackList::Iter i(
callbacks);
00072
for (i.rewind(); i.next(); )
00073 {
00074
WvForkCallback *cb = i.ptr();
00075 (*cb)(pid);
00076 }
00077
00078
if (pid < 0)
00079
return pid;
00080
else if (pid > 0)
00081 {
00082
00083
00084
char buf;
00085 close(waitpipe[1]);
00086 read(waitpipe[0], &buf, 1);
00087 close(waitpipe[0]);
00088 }
00089
else
00090 {
00091
00092 close(waitpipe[0]);
00093 *waitfd = waitpipe[1];
00094 }
00095
00096
return pid;
00097 }
00098
00099 pid_t
wvfork(intTable &dontclose)
00100 {
00101
int waitfd = -1;
00102 pid_t pid =
wvfork_start(&waitfd);
00103
00104
if (pid != 0)
00105 {
00106
00107
return pid;
00108 }
00109
00110
00111
00112
for (
int fd = 0; fd <
MAX_FD; fd++)
00113 {
00114
if (!dontclose[fd] && fd != waitfd &&
00115 (fcntl(fd, F_GETFD) & FD_CLOEXEC) > 0)
00116 close(fd);
00117 }
00118
00119 close(waitfd);
00120
00121
return pid;
00122 }