1 /* run.c --- routines for executing subprocesses.
3 This file is part of GNU CVS.
5 GNU CVS is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details. */
18 extern int execvp (char *file, char **argv);
21 static void run_add_arg (const char *s);
26 * To exec a program under CVS, first call run_setup() to setup initial
27 * arguments. The argument to run_setup will be parsed into whitespace
28 * separated words and added to the global run_argv list.
30 * Then, optionally call run_arg() for each additional argument that you'd like
31 * to pass to the executed program.
33 * Finally, call run_exec() to execute the program with the specified arguments.
34 * The execvp() syscall will be used, so that the PATH is searched correctly.
35 * File redirections can be performed in the call to run_exec().
37 static char **run_argv;
39 static int run_argc_allocated;
43 run_setup( const char *prog )
53 /* clean out any malloc'ed values from run_argv */
54 for (i = 0; i < run_argc; i++)
64 run_prog = xstrdup (prog);
72 expand_string(&buf, &length, doff + 1);
74 while ((*d = *s++) != '\0')
84 if (inquotes == *d) inquotes = '\0';
95 while (isspace(*s)) s++;
96 if (!*s) dolastarg = 0;
104 expand_string(&buf, &length, doff + 1);
107 if (dolastarg) run_add_arg (buf);
108 /* put each word into run_argv, allocating it as we go */
116 run_arg (const char *s)
124 run_add_arg (const char *s)
126 /* allocate more argv entries if we've run out */
127 if (run_argc >= run_argc_allocated)
129 run_argc_allocated += 50;
130 run_argv = xrealloc (run_argv, run_argc_allocated * sizeof (char **));
134 run_argv[run_argc++] = xstrdup (s);
136 run_argv[run_argc] = NULL; /* not post-incremented on purpose! */
142 run_exec (const char *stin, const char *stout, const char *sterr, int flags)
144 int shin, shout, sherr;
145 int mode_out, mode_err;
152 sigset_t sigset_mask, sigset_omask;
153 struct sigaction act, iact, qact;
158 struct sigvec vec, ivec, qvec;
161 RETSIGTYPE (*istat) (), (*qstat) ();
168 #ifdef SERVER_SUPPORT
169 server_active ? "S" :
172 cvs_outerr (" -> system (", 0);
174 cvs_outerr (")\n", 0);
176 if (noexec && (flags & RUN_REALLY) == 0)
179 /* make sure that we are null terminated, since we didn't calloc */
182 /* setup default file descriptor numbers */
187 /* set the file modes for stdout and stderr */
188 mode_out = mode_err = O_WRONLY | O_CREAT;
189 mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC);
190 mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
192 if (stin && (shin = open (stin, O_RDONLY)) == -1)
195 error (0, errno, "cannot open %s for reading (prog %s)",
199 if (stout && (shout = open (stout, mode_out, 0666)) == -1)
202 error (0, errno, "cannot open %s for writing (prog %s)",
206 if (sterr && (flags & RUN_COMBINED) == 0)
208 if ((sherr = open (sterr, mode_err, 0666)) == -1)
211 error (0, errno, "cannot open %s for writing (prog %s)",
217 /* Make sure we don't flush this twice, once in the subprocess. */
221 /* The output files, if any, are now created. Do the fork and dups.
223 We use vfork not so much for a performance boost (the
224 performance boost, if any, is modest on most modern unices),
225 but for the sake of systems without a memory management unit,
226 which find it difficult or impossible to implement fork at all
227 (e.g. Amiga). The other solution is spawn (see
228 windows-NT/run.c). */
239 (void) dup2 (shin, 0);
244 (void) dup2 (shout, 1);
245 (void) close (shout);
247 if (flags & RUN_COMBINED)
251 (void) dup2 (sherr, 2);
252 (void) close (sherr);
255 #ifdef SETXID_SUPPORT
257 ** This prevents a user from creating a privileged shell
258 ** from the text editor when the SETXID_SUPPORT option is selected.
260 if (!strcmp (run_argv[0], Editor) && setegid (getgid ()))
262 error (0, errno, "cannot set egid to gid");
267 /* dup'ing is done. try to run it now */
268 (void) execvp (run_argv[0], run_argv);
269 error (0, errno, "cannot exec %s", run_argv[0]);
278 /* the parent. Ignore some signals for now */
280 if (flags & RUN_SIGIGNORE)
282 act.sa_handler = SIG_IGN;
283 (void) sigemptyset (&act.sa_mask);
285 (void) sigaction (SIGINT, &act, &iact);
286 (void) sigaction (SIGQUIT, &act, &qact);
290 (void) sigemptyset (&sigset_mask);
291 (void) sigaddset (&sigset_mask, SIGINT);
292 (void) sigaddset (&sigset_mask, SIGQUIT);
293 (void) sigprocmask (SIG_SETMASK, &sigset_mask, &sigset_omask);
297 if (flags & RUN_SIGIGNORE)
299 memset (&vec, 0, sizeof vec);
300 vec.sv_handler = SIG_IGN;
301 (void) sigvec (SIGINT, &vec, &ivec);
302 (void) sigvec (SIGQUIT, &vec, &qvec);
305 mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT));
307 istat = signal (SIGINT, SIG_IGN);
308 qstat = signal (SIGQUIT, SIG_IGN);
312 /* wait for our process to die and munge return status */
314 while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
317 while ((w = wait (&status)) != pid)
319 if (w == -1 && errno != EINTR)
329 #ifndef VMS /* status is return status */
330 else if (WIFEXITED (status))
331 rc = WEXITSTATUS (status);
332 else if (WIFSIGNALED (status))
334 if (WTERMSIG (status) == SIGPIPE)
335 error (1, 0, "broken pipe");
341 rc = WEXITSTATUS (status);
344 /* restore the signals */
346 if (flags & RUN_SIGIGNORE)
348 (void) sigaction (SIGINT, &iact, NULL);
349 (void) sigaction (SIGQUIT, &qact, NULL);
352 (void) sigprocmask (SIG_SETMASK, &sigset_omask, NULL);
355 if (flags & RUN_SIGIGNORE)
357 (void) sigvec (SIGINT, &ivec, NULL);
358 (void) sigvec (SIGQUIT, &qvec, NULL);
361 (void) sigsetmask (mask);
363 (void) signal (SIGINT, istat);
364 (void) signal (SIGQUIT, qstat);
368 /* cleanup the open file descriptors */
371 (void) close (sherr);
373 /* ensure things are received by the parent in the correct order
374 * relative to the protocol pipe
379 (void) close (shout);
381 /* ensure things are received by the parent in the correct order
382 * relative to the protocol pipe
401 void (*outfn) (const char *, size_t);
405 else if (fp == stdout)
409 error (1, 0, "internal error: bad argument to run_print");
410 /* Solely to placate gcc -Wall.
411 FIXME: it'd be better to use a function named `fatal' that
412 is known never to return. Then kludges wouldn't be necessary. */
416 for (i = 0; i < run_argc; i++)
419 (*outfn) (run_argv[i], 0);
421 if (i != run_argc - 1)
428 /* Return value is NULL for error, or if noexec was set. If there was an
429 error, return NULL and I'm not sure whether errno was set (the Red Hat
430 Linux 4.1 popen manpage was kind of vague but discouraging; and the noexec
431 case complicates this even aside from popen behavior). */
433 run_popen (const char *cmd, const char *mode)
435 TRACE ( 1, "run_popen(%s,%s)", cmd, mode );
439 return (popen (cmd, mode));
445 piped_child (char *const *command, int *tofdp, int *fromfdp)
448 int to_child_pipe[2];
449 int from_child_pipe[2];
451 if (pipe (to_child_pipe) < 0)
452 error (1, errno, "cannot create pipe");
453 if (pipe (from_child_pipe) < 0)
454 error (1, errno, "cannot create pipe");
456 #ifdef USE_SETMODE_BINARY
457 setmode (to_child_pipe[0], O_BINARY);
458 setmode (to_child_pipe[1], O_BINARY);
459 setmode (from_child_pipe[0], O_BINARY);
460 setmode (from_child_pipe[1], O_BINARY);
469 error (1, errno, "cannot fork");
472 if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0)
473 error (1, errno, "cannot dup2 pipe");
474 if (close (to_child_pipe[1]) < 0)
475 error (1, errno, "cannot close pipe");
476 if (close (from_child_pipe[0]) < 0)
477 error (1, errno, "cannot close pipe");
478 if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
479 error (1, errno, "cannot dup2 pipe");
481 /* Okay to cast out const below - execvp don't return anyhow. */
482 execvp ((char *)command[0], (char **)command);
483 error (1, errno, "cannot exec %s", command[0]);
485 if (close (to_child_pipe[0]) < 0)
486 error (1, errno, "cannot close pipe");
487 if (close (from_child_pipe[1]) < 0)
488 error (1, errno, "cannot close pipe");
490 *tofdp = to_child_pipe[1];
491 *fromfdp = from_child_pipe[0];
498 close_on_exec (int fd)
501 if (fcntl (fd, F_SETFD, 1) == -1)
502 error (1, errno, "can't set close-on-exec flag on %d", fd);