Line data Source code
1 : #include "burp.h"
2 : #include "forkchild.h"
3 : #include "fzp.h"
4 : #include "log.h"
5 :
6 : #ifdef HAVE_WIN32
7 : // Windows version of forkchild is in src/win32/compat/compat.cpp
8 : #else
9 :
10 0 : static pid_t do_forkchild(int sin, int sout, int serr,
11 : const char *path, char * const argv[])
12 : {
13 : pid_t pid;
14 :
15 0 : if((pid=fork())<0) return -1;
16 0 : else if(!pid)
17 : {
18 : int fd;
19 0 : if((sin>=0 && dup2(sin, STDIN_FILENO)<0)
20 0 : || (sout>=0 && dup2(sout, STDOUT_FILENO)<0)
21 0 : || (serr>=0 && dup2(serr, STDERR_FILENO)<0))
22 : {
23 0 : logp("dup2: %s\n", strerror(errno));
24 0 : return -1;
25 : }
26 0 : if(sout>=0) setbuf(stdout, NULL);
27 0 : if(serr>=0) setbuf(stderr, NULL);
28 : /* Close all unused file descriptors before exec.
29 : * FD_SETSIZE is not strictly the highest file descriptor-1,
30 : * but there does not appear to be a sensible way to find out
31 : * the true number, and FD_SETSIZE is a close approximation.
32 : * It would be a bit lame if you could open a file whose
33 : * descriptor could not be included in an fd_set. */
34 0 : for(fd=3; fd<(int)FD_SETSIZE; ++fd) close(fd);
35 0 : if(execv(path, argv))
36 0 : logp("execv %s: %s\n", path, strerror(errno));
37 0 : exit(1);
38 : }
39 : return pid;
40 : }
41 :
42 0 : pid_t forkchild(struct fzp **sin, struct fzp **sout, struct fzp **serr,
43 : const char *path, char * const argv[])
44 : {
45 : pid_t pid;
46 : int sinfds[2];
47 : int soutfds[2];
48 : int serrfds[2];
49 :
50 0 : if((sin && pipe(sinfds))
51 0 : || (sout && pipe(soutfds))
52 0 : || (serr && pipe(serrfds)))
53 : return -1;
54 0 : if((sin && !(*sin=fzp_dopen(sinfds[1], "w")))
55 0 : || (sout && !(*sout=fzp_dopen(soutfds[0], "r")))
56 0 : || (serr && !(*serr=fzp_dopen(serrfds[0], "r"))))
57 : return -1;
58 : pid=do_forkchild(sin?sinfds[0]:-1, sout?soutfds[1]:-1,
59 0 : serr?serrfds[1]:-1, path, argv);
60 0 : if(sin) close(sinfds[0]);
61 0 : if(sout) close(soutfds[1]);
62 0 : if(serr) close(serrfds[1]);
63 0 : return pid;
64 : }
65 :
66 0 : pid_t forkchild_fd(int *sin, int *sout, int *serr,
67 : const char *path, char * const argv[])
68 : {
69 : pid_t pid;
70 : int sinfds[2];
71 : int soutfds[2];
72 : int serrfds[2];
73 :
74 0 : if((sin && pipe(sinfds))
75 0 : || (sout && pipe(soutfds))
76 0 : || (serr && pipe(serrfds)))
77 : return -1;
78 0 : if(sin) *sin=sinfds[1];
79 0 : if(sout) *sout=soutfds[0];
80 0 : if(serr) *serr=serrfds[0];
81 : pid=do_forkchild(sin?sinfds[0]:-1, sout?soutfds[1]:-1,
82 0 : serr?serrfds[1]:-1, path, argv);
83 0 : if(sin) close(sinfds[0]);
84 0 : if(sout) close(soutfds[1]);
85 0 : if(serr) close(serrfds[1]);
86 0 : return pid;
87 : }
88 :
89 0 : pid_t forkchild_no_wait(struct fzp **sin, struct fzp **sout, struct fzp **serr,
90 : const char *path, char * const argv[])
91 : {
92 0 : return forkchild(sin, sout, serr, path, argv);
93 : }
94 :
95 : #endif
|