9 * this used to be a function in it's own write but became a wrapper around
10 * pipespawnv to eliminate redundancy...
13 int pipespawn(char *prog, int pipedef, int *stdinfd, int *stdoutfd,
16 int pipespawn(prog, pipedef, stdinfd, stdoutfd, stderrfd, va_alist)
19 int *stdinfd, *stdoutfd, *stderrfd;
28 arglist_start(ap, stderrfd);
29 while(arglist_val(ap, char *) != NULL) {
35 * Create the argument vector.
37 arglist_start(ap, stderrfd);
38 argv = (char **)alloc((argc + 1) * sizeof(*argv));
40 while((argv[i] = arglist_val(ap, char *)) != NULL) {
41 if (argv[i] != skip_argument) {
47 pid = pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, NULL, NULL, argv);
52 int pipespawnv(prog, pipedef, stdinfd, stdoutfd, stderrfd, my_argv)
55 int *stdinfd, *stdoutfd, *stderrfd;
58 return pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd,
62 int pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, passwdvar, passwdfd, my_argv)
65 int *stdinfd, *stdoutfd, *stderrfd;
71 int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
72 char number[NUM_STR_SIZE];
80 * Log the command line and count the args.
82 dbprintf(("%s: spawning %s in pipeline\n", debug_prefix_time(NULL), prog));
83 dbprintf(("%s: argument list:", debug_prefix(NULL)));
84 if ((pipedef & PASSWD_PIPE) != 0) {
85 passwdvar = *my_argv++;
86 passwdfd = (int *)*my_argv++;
89 for(arg = my_argv; *arg != NULL; arg++) {
90 if (*arg == skip_argument) {
95 for(i = 0; (ch = (*arg)[i]) != '\0' && isprint(ch) && ch != ' '; i++) {}
96 if(ch != '\0' || i == 0) {
99 dbprintf(("%s", *arg));
100 if(ch != '\0' || i == 0) {
109 if ((pipedef & STDIN_PIPE) != 0) {
110 if(pipe(inpipe) == -1) {
111 error("error [open pipe to %s: %s]", prog, strerror(errno));
114 if ((pipedef & STDOUT_PIPE) != 0) {
115 if(pipe(outpipe) == -1) {
116 error("error [open pipe to %s: %s]", prog, strerror(errno));
119 if ((pipedef & STDERR_PIPE) != 0) {
120 if(pipe(errpipe) == -1) {
121 error("error [open pipe to %s: %s]", prog, strerror(errno));
124 if ((pipedef & PASSWD_PIPE) != 0) {
125 if(pipe(passwdpipe) == -1) {
126 error("error [open pipe to %s: %s]", prog, strerror(errno));
131 * Fork and set up the return or run the program.
133 switch(pid = fork()) {
136 error("error [fork %s: %s]", prog, e);
137 default: /* parent process */
138 if ((pipedef & STDIN_PIPE) != 0) {
139 aclose(inpipe[0]); /* close input side of pipe */
140 *stdinfd = inpipe[1];
142 if ((pipedef & STDOUT_PIPE) != 0) {
143 aclose(outpipe[1]); /* close output side of pipe */
144 *stdoutfd = outpipe[0];
146 if ((pipedef & STDERR_PIPE) != 0) {
147 aclose(errpipe[1]); /* close output side of pipe */
148 *stderrfd = errpipe[0];
150 if ((pipedef & PASSWD_PIPE) != 0) {
151 aclose(passwdpipe[0]); /* close input side of pipe */
152 *passwdfd = passwdpipe[1];
155 case 0: /* child process */
156 if ((pipedef & STDIN_PIPE) != 0) {
157 aclose(inpipe[1]); /* close output side of pipe */
159 inpipe[0] = *stdinfd;
161 if ((pipedef & STDOUT_PIPE) != 0) {
162 aclose(outpipe[0]); /* close input side of pipe */
164 outpipe[1] = *stdoutfd;
166 if ((pipedef & STDERR_PIPE) != 0) {
167 aclose(errpipe[0]); /* close input side of pipe */
169 errpipe[1] = *stderrfd;
171 if ((pipedef & PASSWD_PIPE) != 0) {
172 aclose(passwdpipe[1]); /* close output side of pipe */
176 * Shift the pipes to the standard file descriptors as requested.
178 if(dup2(inpipe[0], 0) == -1) {
179 error("error [spawn %s: dup2 in: %s]", prog, strerror(errno));
181 if(dup2(outpipe[1], 1) == -1) {
182 error("error [spawn %s: dup2 out: %s]", prog, strerror(errno));
184 if(dup2(errpipe[1], 2) == -1) {
185 error("error [spawn %s: dup2 err: %s]", prog, strerror(errno));
189 * Get the "safe" environment. If we are sending a password to
190 * the child via a pipe, add the environment variable for that.
193 if ((pipedef & PASSWD_PIPE) != 0) {
194 for(i = 0; env[i] != NULL; i++) {}
195 newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv));
196 snprintf(number, sizeof(number), "%d", passwdpipe[0]);
197 newenv[0] = vstralloc(passwdvar, "=", number, NULL);
198 for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {}
203 execve(prog, my_argv, env);
205 error("error [exec %s: %s]", prog, e);