9 int pipespawn(char *prog, int pipedef, int *stdinfd, int *stdoutfd,
12 int pipespawn(prog, pipedef, stdinfd, stdoutfd, stderrfd, va_alist)
15 int *stdinfd, *stdoutfd, *stderrfd;
22 int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
23 char *passwdvar = NULL;
25 char number[NUM_STR_SIZE];
33 * Log the command line and count the args.
35 dbprintf(("%s: spawning %s in pipeline\n", debug_prefix_time(NULL), prog));
36 dbprintf(("%s: argument list:", debug_prefix(NULL)));
37 arglist_start(ap, stderrfd);
38 if ((pipedef & PASSWD_PIPE) != 0) {
39 passwdvar = arglist_val(ap, char *);
40 passwdfd = arglist_val(ap, int *);
43 while((arg = arglist_val(ap, char *)) != NULL) {
44 if (arg == skip_argument) {
49 for(i = 0; (ch = arg[i]) != '\0' && isprint(ch) && ch != ' '; i++) {}
50 if(ch != '\0' || i == 0) {
53 dbprintf(("%s", arg));
54 if(ch != '\0' || i == 0) {
64 if ((pipedef & STDIN_PIPE) != 0) {
65 if(pipe(inpipe) == -1) {
66 error("error [open pipe to %s: %s]", prog, strerror(errno));
69 if ((pipedef & STDOUT_PIPE) != 0) {
70 if(pipe(outpipe) == -1) {
71 error("error [open pipe to %s: %s]", prog, strerror(errno));
74 if ((pipedef & STDERR_PIPE) != 0) {
75 if(pipe(errpipe) == -1) {
76 error("error [open pipe to %s: %s]", prog, strerror(errno));
79 if ((pipedef & PASSWD_PIPE) != 0) {
80 if(pipe(passwdpipe) == -1) {
81 error("error [open pipe to %s: %s]", prog, strerror(errno));
86 * Fork and set up the return or run the program.
88 switch(pid = fork()) {
91 error("error [fork %s: %s]", prog, e);
92 default: /* parent process */
93 if ((pipedef & STDIN_PIPE) != 0) {
94 aclose(inpipe[0]); /* close input side of pipe */
97 if ((pipedef & STDOUT_PIPE) != 0) {
98 aclose(outpipe[1]); /* close output side of pipe */
99 *stdoutfd = outpipe[0];
101 if ((pipedef & STDERR_PIPE) != 0) {
102 aclose(errpipe[1]); /* close output side of pipe */
103 *stderrfd = errpipe[0];
105 if ((pipedef & PASSWD_PIPE) != 0) {
106 aclose(passwdpipe[0]); /* close input side of pipe */
107 *passwdfd = passwdpipe[1];
110 case 0: /* child process */
111 if ((pipedef & STDIN_PIPE) != 0) {
112 aclose(inpipe[1]); /* close output side of pipe */
114 inpipe[0] = *stdinfd;
116 if ((pipedef & STDOUT_PIPE) != 0) {
117 aclose(outpipe[0]); /* close input side of pipe */
119 outpipe[1] = *stdoutfd;
121 if ((pipedef & STDERR_PIPE) != 0) {
122 aclose(errpipe[0]); /* close input side of pipe */
124 errpipe[1] = *stderrfd;
126 if ((pipedef & PASSWD_PIPE) != 0) {
127 aclose(passwdpipe[1]); /* close output side of pipe */
131 * Shift the pipes to the standard file descriptors as requested.
133 if(dup2(inpipe[0], 0) == -1) {
134 error("error [spawn %s: dup2 in: %s]", prog, strerror(errno));
136 if(dup2(outpipe[1], 1) == -1) {
137 error("error [spawn %s: dup2 out: %s]", prog, strerror(errno));
139 if(dup2(errpipe[1], 2) == -1) {
140 error("error [spawn %s: dup2 err: %s]", prog, strerror(errno));
144 * Create the argument vector.
146 arglist_start(ap, stderrfd);
147 if ((pipedef & PASSWD_PIPE) != 0) {
148 passwdvar = arglist_val(ap, char *);
149 passwdfd = arglist_val(ap, int *);
151 argv = (char **)alloc((argc + 1) * sizeof(*argv));
153 while((argv[i] = arglist_val(ap, char *)) != NULL) {
154 if (argv[i] != skip_argument) {
161 * Get the "safe" environment. If we are sending a password to
162 * the child via a pipe, add the environment variable for that.
165 if ((pipedef & PASSWD_PIPE) != 0) {
166 for(i = 0; env[i] != NULL; i++) {}
167 newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv));
168 ap_snprintf(number, sizeof(number), "%d", passwdpipe[0]);
169 newenv[0] = vstralloc(passwdvar, "=", number, NULL);
170 for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {}
174 execve(prog, argv, env);
176 error("error [exec %s: %s]", prog, e);
182 int pipespawnv(prog, pipedef, stdinfd, stdoutfd, stderrfd, my_argv)
185 int *stdinfd, *stdoutfd, *stderrfd;
189 int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
190 char *passwdvar = NULL;
191 int *passwdfd = NULL;
192 char number[NUM_STR_SIZE];
200 * Log the command line and count the args.
202 dbprintf(("%s: spawning %s in pipeline\n", debug_prefix_time(NULL), prog));
203 dbprintf(("%s: argument list:", debug_prefix(NULL)));
204 if ((pipedef & PASSWD_PIPE) != 0) {
205 passwdvar = *my_argv++;
206 passwdfd = (int *)*my_argv++;
209 for(arg = my_argv; *arg != NULL; arg++) {
210 if (*arg == skip_argument) {
215 for(i = 0; (ch = (*arg)[i]) != '\0' && isprint(ch) && ch != ' '; i++) {}
216 if(ch != '\0' || i == 0) {
219 dbprintf(("%s", *arg));
220 if(ch != '\0' || i == 0) {
229 if ((pipedef & STDIN_PIPE) != 0) {
230 if(pipe(inpipe) == -1) {
231 error("error [open pipe to %s: %s]", prog, strerror(errno));
234 if ((pipedef & STDOUT_PIPE) != 0) {
235 if(pipe(outpipe) == -1) {
236 error("error [open pipe to %s: %s]", prog, strerror(errno));
239 if ((pipedef & STDERR_PIPE) != 0) {
240 if(pipe(errpipe) == -1) {
241 error("error [open pipe to %s: %s]", prog, strerror(errno));
244 if ((pipedef & PASSWD_PIPE) != 0) {
245 if(pipe(passwdpipe) == -1) {
246 error("error [open pipe to %s: %s]", prog, strerror(errno));
251 * Fork and set up the return or run the program.
253 switch(pid = fork()) {
256 error("error [fork %s: %s]", prog, e);
257 default: /* parent process */
258 if ((pipedef & STDIN_PIPE) != 0) {
259 aclose(inpipe[0]); /* close input side of pipe */
260 *stdinfd = inpipe[1];
262 if ((pipedef & STDOUT_PIPE) != 0) {
263 aclose(outpipe[1]); /* close output side of pipe */
264 *stdoutfd = outpipe[0];
266 if ((pipedef & STDERR_PIPE) != 0) {
267 aclose(errpipe[1]); /* close output side of pipe */
268 *stderrfd = errpipe[0];
270 if ((pipedef & PASSWD_PIPE) != 0) {
271 aclose(passwdpipe[0]); /* close input side of pipe */
272 *passwdfd = passwdpipe[1];
275 case 0: /* child process */
276 if ((pipedef & STDIN_PIPE) != 0) {
277 aclose(inpipe[1]); /* close output side of pipe */
279 inpipe[0] = *stdinfd;
281 if ((pipedef & STDOUT_PIPE) != 0) {
282 aclose(outpipe[0]); /* close input side of pipe */
284 outpipe[1] = *stdoutfd;
286 if ((pipedef & STDERR_PIPE) != 0) {
287 aclose(errpipe[0]); /* close input side of pipe */
289 errpipe[1] = *stderrfd;
293 * Shift the pipes to the standard file descriptors as requested.
295 if(dup2(inpipe[0], 0) == -1) {
296 error("error [spawn %s: dup2 in: %s]", prog, strerror(errno));
298 if(dup2(outpipe[1], 1) == -1) {
299 error("error [spawn %s: dup2 out: %s]", prog, strerror(errno));
301 if(dup2(errpipe[1], 2) == -1) {
302 error("error [spawn %s: dup2 err: %s]", prog, strerror(errno));
306 * Get the "safe" environment. If we are sending a password to
307 * the child via a pipe, add the environment variable for that.
310 if ((pipedef & PASSWD_PIPE) != 0) {
311 for(i = 0; env[i] != NULL; i++) {}
312 newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv));
313 ap_snprintf(number, sizeof(number), "%d", passwdpipe[0]);
314 newenv[0] = vstralloc(passwdvar, "=", number, NULL);
315 for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {}
319 execve(prog, my_argv, env);
321 error("error [exec %s: %s]", prog, e);