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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
24 #define VA_START(args, lastarg) va_start(args, lastarg)
27 #define VA_START(args, lastarg) va_start(args)
30 #define va_alist a1, a2, a3, a4, a5, a6, a7, a8
31 #define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
34 static void run_add_arg PROTO((const char *s));
35 static void run_init_prog PROTO((void));
37 extern char *strtok ();
40 * To exec a program under CVS, first call run_setup() to setup any initial
41 * arguments. The options to run_setup are essentially like printf(). The
42 * arguments will be parsed into whitespace separated words and added to the
43 * global run_argv list.
45 * Then, optionally call run_arg() for each additional argument that you'd like
46 * to pass to the executed program.
48 * Finally, call run_exec() to execute the program with the specified arguments.
49 * The execvp() syscall will be used, so that the PATH is searched correctly.
50 * File redirections can be performed in the call to run_exec().
52 static char *run_prog;
53 static char **run_argv;
55 static int run_argc_allocated;
58 #if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
60 run_setup (const char *fmt,...)
63 run_setup (fmt, va_alist)
76 /* clean out any malloc'ed values from run_argv */
77 for (i = 0; i < run_argc; i++)
82 run_argv[i] = (char *) 0;
87 /* process the varargs into run_prog */
90 (void) vsprintf (run_prog, fmt, args);
93 (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
96 /* put each word into run_argv, allocating it as we go */
97 for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
109 #if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
111 run_args (const char *fmt,...)
114 run_args (fmt, va_alist)
125 /* process the varargs into run_prog */
127 VA_START (args, fmt);
128 (void) vsprintf (run_prog, fmt, args);
131 (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
134 /* and add the (single) argument to the run_argv list */
135 run_add_arg (run_prog);
142 /* allocate more argv entries if we've run out */
143 if (run_argc >= run_argc_allocated)
145 run_argc_allocated += 50;
146 run_argv = (char **) xrealloc ((char *) run_argv,
147 run_argc_allocated * sizeof (char **));
151 run_argv[run_argc++] = xstrdup (s);
153 run_argv[run_argc] = (char *) 0; /* not post-incremented on purpose! */
159 /* make sure that run_prog is allocated once */
160 if (run_prog == (char *) 0)
161 run_prog = xmalloc (10 * 1024); /* 10K of args for _setup and _arg */
165 run_exec (stin, stout, sterr, flags)
171 int shin, shout, sherr;
172 int mode_out, mode_err;
179 sigset_t sigset_mask, sigset_omask;
180 struct sigaction act, iact, qact;
185 struct sigvec vec, ivec, qvec;
188 RETSIGTYPE (*istat) (), (*qstat) ();
194 #ifdef SERVER_SUPPORT
195 (void) fprintf (stderr, "%c-> system(", (server_active) ? 'S' : ' ');
197 (void) fprintf (stderr, "-> system(");
200 (void) fprintf (stderr, ")\n");
202 if (noexec && (flags & RUN_REALLY) == 0)
205 /* make sure that we are null terminated, since we didn't calloc */
206 run_add_arg ((char *) 0);
208 /* setup default file descriptor numbers */
213 /* set the file modes for stdout and stderr */
214 mode_out = mode_err = O_WRONLY | O_CREAT;
215 mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC);
216 mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
218 if (stin && (shin = open (stin, O_RDONLY)) == -1)
221 error (0, errno, "cannot open %s for reading (prog %s)",
225 if (stout && (shout = open (stout, mode_out, 0666)) == -1)
228 error (0, errno, "cannot open %s for writing (prog %s)",
232 if (sterr && (flags & RUN_COMBINED) == 0)
234 if ((sherr = open (sterr, mode_err, 0666)) == -1)
237 error (0, errno, "cannot open %s for writing (prog %s)",
243 /* Make sure we don't flush this twice, once in the subprocess. */
247 /* The output files, if any, are now created. Do the fork and dups */
257 (void) dup2 (shin, 0);
262 (void) dup2 (shout, 1);
263 (void) close (shout);
265 if (flags & RUN_COMBINED)
269 (void) dup2 (sherr, 2);
270 (void) close (sherr);
273 /* dup'ing is done. try to run it now */
274 (void) execvp (run_argv[0], run_argv);
275 error (0, errno, "cannot exec %s", run_argv[0]);
284 /* the parent. Ignore some signals for now */
286 if (flags & RUN_SIGIGNORE)
288 act.sa_handler = SIG_IGN;
289 (void) sigemptyset (&act.sa_mask);
291 (void) sigaction (SIGINT, &act, &iact);
292 (void) sigaction (SIGQUIT, &act, &qact);
296 (void) sigemptyset (&sigset_mask);
297 (void) sigaddset (&sigset_mask, SIGINT);
298 (void) sigaddset (&sigset_mask, SIGQUIT);
299 (void) sigprocmask (SIG_SETMASK, &sigset_mask, &sigset_omask);
303 if (flags & RUN_SIGIGNORE)
305 memset ((char *) &vec, 0, sizeof (vec));
306 vec.sv_handler = SIG_IGN;
307 (void) sigvec (SIGINT, &vec, &ivec);
308 (void) sigvec (SIGQUIT, &vec, &qvec);
311 mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT));
313 istat = signal (SIGINT, SIG_IGN);
314 qstat = signal (SIGQUIT, SIG_IGN);
318 /* wait for our process to die and munge return status */
320 while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
323 while ((w = wait (&status)) != pid)
325 if (w == -1 && errno != EINTR)
335 #ifndef VMS /* status is return status */
336 else if (WIFEXITED (status))
337 rc = WEXITSTATUS (status);
338 else if (WIFSIGNALED (status))
340 if (WTERMSIG (status) == SIGPIPE)
341 error (1, 0, "broken pipe");
347 rc = WEXITSTATUS (status);
350 /* restore the signals */
352 if (flags & RUN_SIGIGNORE)
354 (void) sigaction (SIGINT, &iact, (struct sigaction *) NULL);
355 (void) sigaction (SIGQUIT, &qact, (struct sigaction *) NULL);
358 (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *) NULL);
361 if (flags & RUN_SIGIGNORE)
363 (void) sigvec (SIGINT, &ivec, (struct sigvec *) NULL);
364 (void) sigvec (SIGQUIT, &qvec, (struct sigvec *) NULL);
367 (void) sigsetmask (mask);
369 (void) signal (SIGINT, istat);
370 (void) signal (SIGQUIT, qstat);
374 /* cleanup the open file descriptors */
377 (void) close (sherr);
380 (void) close (shout);
397 for (i = 0; i < run_argc; i++)
399 (void) fprintf (fp, "'%s'", run_argv[i]);
400 if (i != run_argc - 1)
401 (void) fprintf (fp, " ");
406 run_popen (cmd, mode)
411 #ifdef SERVER_SUPPORT
412 (void) fprintf (stderr, "%c-> run_popen(%s,%s)\n",
413 (server_active) ? 'S' : ' ', cmd, mode);
415 (void) fprintf (stderr, "-> run_popen(%s,%s)\n", cmd, mode);
420 return (popen (cmd, mode));
423 extern int evecvp PROTO((char *file, char **argv));
426 piped_child (command, tofdp, fromfdp)
432 int to_child_pipe[2];
433 int from_child_pipe[2];
435 if (pipe (to_child_pipe) < 0)
436 error (1, errno, "cannot create pipe");
437 if (pipe (from_child_pipe) < 0)
438 error (1, errno, "cannot create pipe");
442 error (1, errno, "cannot fork");
445 if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0)
446 error (1, errno, "cannot dup2");
447 if (close (to_child_pipe[1]) < 0)
448 error (1, errno, "cannot close");
449 if (close (from_child_pipe[0]) < 0)
450 error (1, errno, "cannot close");
451 if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
452 error (1, errno, "cannot dup2");
454 execvp (command[0], command);
455 error (1, errno, "cannot exec");
457 if (close (to_child_pipe[0]) < 0)
458 error (1, errno, "cannot close");
459 if (close (from_child_pipe[1]) < 0)
460 error (1, errno, "cannot close");
462 *tofdp = to_child_pipe[1];
463 *fromfdp = from_child_pipe[0];
472 #if defined (FD_CLOEXEC) && defined (F_SETFD)
473 if (fcntl (fd, F_SETFD, 1))
474 error (1, errno, "can't set close-on-exec flag on %d", fd);
479 * dir = 0 : main proc writes to new proc, which writes to oldfd
480 * dir = 1 : main proc reads from new proc, which reads from oldfd
482 * Returns: a file descriptor. On failure (i.e., the exec fails),
483 * then filter_stream_through_program() complains and dies.
487 filter_stream_through_program (oldfd, dir, prog, pidp)
496 error (1, errno, "cannot create pipe");
503 error (1, errno, "cannot fork");
508 /* write to new pipe */
515 /* read from new pipe */
520 /* Should I be blocking some signals here? */
521 execvp (prog[0], prog);
522 error (1, errno, "couldn't exec %s", prog[0]);
528 /* read from new pipe */
534 /* write to new pipe */
538 close_on_exec (newfd);