9 pid_t pipespawnv_passwd(char *prog, int pipedef,
10 int *stdinfd, int *stdoutfd, int *stderrfd,
15 * this used to be a function in it's own write but became a wrapper around
16 * pipespawnv to eliminate redundancy...
33 arglist_start(ap, stderrfd);
34 while(arglist_val(ap, char *) != NULL) {
40 * Create the argument vector.
42 arglist_start(ap, stderrfd);
43 argv = (char **)alloc((argc + 1) * SIZEOF(*argv));
45 while((argv[i] = arglist_val(ap, char *)) != NULL) {
46 if (argv[i] != skip_argument) {
52 pid = pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, argv);
66 return pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd,
81 int i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
82 char number[NUM_STR_SIZE];
87 char *passwdvar = NULL;
91 * Log the command line and count the args.
93 dbprintf(("%s: spawning %s in pipeline\n", debug_prefix_time(NULL), prog));
94 dbprintf(("%s: argument list:", debug_prefix_time(NULL)));
95 if ((pipedef & PASSWD_PIPE) != 0) {
96 passwdvar = *my_argv++;
97 passwdfd = (int *)*my_argv++;
99 memset(inpipe, -1, SIZEOF(inpipe));
100 memset(outpipe, -1, SIZEOF(outpipe));
101 memset(errpipe, -1, SIZEOF(errpipe));
102 memset(passwdpipe, -1, SIZEOF(passwdpipe));
104 for(arg = my_argv; *arg != NULL; arg++) {
107 if (*arg != skip_argument) {
109 quoted = quote_string(*arg);
110 dbprintf((" %s", quoted));
119 if ((pipedef & STDIN_PIPE) != 0) {
120 if(pipe(inpipe) == -1) {
121 error("error [open pipe to %s: %s]", prog, strerror(errno));
125 if ((pipedef & STDOUT_PIPE) != 0) {
126 if(pipe(outpipe) == -1) {
127 error("error [open pipe to %s: %s]", prog, strerror(errno));
131 if ((pipedef & STDERR_PIPE) != 0) {
132 if(pipe(errpipe) == -1) {
133 error("error [open pipe to %s: %s]", prog, strerror(errno));
137 if ((pipedef & PASSWD_PIPE) != 0) {
138 if(pipe(passwdpipe) == -1) {
139 error("error [open pipe to %s: %s]", prog, strerror(errno));
145 * Fork and set up the return or run the program.
147 switch(pid = fork()) {
150 error("error [fork %s: %s]", prog, e);
153 default: /* parent process */
154 if ((pipedef & STDIN_PIPE) != 0) {
155 aclose(inpipe[0]); /* close input side of pipe */
156 *stdinfd = inpipe[1];
158 if ((pipedef & STDOUT_PIPE) != 0) {
159 aclose(outpipe[1]); /* close output side of pipe */
160 *stdoutfd = outpipe[0];
162 if ((pipedef & STDERR_PIPE) != 0) {
163 aclose(errpipe[1]); /* close output side of pipe */
164 *stderrfd = errpipe[0];
166 if ((pipedef & PASSWD_PIPE) != 0) {
167 aclose(passwdpipe[0]); /* close input side of pipe */
168 *passwdfd = passwdpipe[1];
171 case 0: /* child process */
172 if ((pipedef & STDIN_PIPE) != 0) {
173 aclose(inpipe[1]); /* close output side of pipe */
175 inpipe[0] = *stdinfd;
177 if ((pipedef & STDOUT_PIPE) != 0) {
178 aclose(outpipe[0]); /* close input side of pipe */
180 outpipe[1] = *stdoutfd;
182 if ((pipedef & STDERR_PIPE) != 0) {
183 aclose(errpipe[0]); /* close input side of pipe */
185 errpipe[1] = *stderrfd;
187 if ((pipedef & PASSWD_PIPE) != 0) {
188 aclose(passwdpipe[1]); /* close output side of pipe */
192 * Shift the pipes to the standard file descriptors as requested.
194 if(dup2(inpipe[0], 0) == -1) {
195 error("error [spawn %s: dup2 in: %s]", prog, strerror(errno));
198 if(dup2(outpipe[1], 1) == -1) {
199 error("error [spawn %s: dup2 out: %s]", prog, strerror(errno));
202 if(dup2(errpipe[1], 2) == -1) {
203 error("error [spawn %s: dup2 err: %s]", prog, strerror(errno));
208 * Get the "safe" environment. If we are sending a password to
209 * the child via a pipe, add the environment variable for that.
212 if ((pipedef & PASSWD_PIPE) != 0) {
213 for (i = 0; env[i] != NULL; i++)
214 (void)i; /* make lint happy and do nothing */
215 newenv = (char **)alloc((i + 1 + 1) * SIZEOF(*newenv));
216 snprintf(number, SIZEOF(number), "%d", passwdpipe[0]);
217 newenv[0] = vstralloc(passwdvar, "=", number, NULL);
218 for(i = 0; env[i] != NULL; i++)
219 newenv[i + 1] = env[i];
220 newenv[i + 1] = NULL;
225 execve(prog, my_argv, env);
227 error("error [exec %s: %s]", prog, e);