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);
24 * To exec a program under CVS, first call run_setup() to setup initial
25 * arguments. The argument to run_setup will be parsed into whitespace
26 * separated words and added to the global run_argv list.
28 * Then, optionally call run_add_arg() for each additional argument that you'd
29 * like to pass to the executed program.
31 * Finally, call run_exec() to execute the program with the specified arguments.
32 * The execvp() syscall will be used, so that the PATH is searched correctly.
33 * File redirections can be performed in the call to run_exec().
35 static char **run_argv;
37 static size_t run_arg_allocated;
42 run_arg_free_p (int argc, char **argv)
45 for (i = 0; i < argc; i++)
53 run_setup (const char *prog)
62 /* clean out any malloc'ed values from run_argv */
63 run_arg_free_p (run_argc, run_argv);
66 run_prog = xstrdup (prog);
74 expand_string(&buf, &length, doff + 1);
76 while ((*d = *s++) != '\0')
86 if (inquotes == *d) inquotes = '\0';
97 while (isspace(*s)) s++;
98 if (!*s) dolastarg = 0;
106 expand_string(&buf, &length, doff + 1);
109 if (dolastarg) run_add_arg (buf);
110 /* put each word into run_argv, allocating it as we go */
118 run_add_arg_p (int *iargc, size_t *iarg_allocated, char ***iargv,
121 /* allocate more argv entries if we've run out */
122 if (*iargc >= *iarg_allocated)
124 *iarg_allocated += 50;
125 *iargv = xnrealloc (*iargv, *iarg_allocated, sizeof (char **));
129 (*iargv)[(*iargc)++] = xstrdup (s);
131 (*iargv)[*iargc] = NULL; /* not post-incremented on purpose! */
137 run_add_arg (const char *s)
139 run_add_arg_p (&run_argc, &run_arg_allocated, &run_argv, s);
145 run_exec (const char *stin, const char *stout, const char *sterr, int flags)
147 int shin, shout, sherr;
148 int mode_out, mode_err;
155 sigset_t sigset_mask, sigset_omask;
156 struct sigaction act, iact, qact;
161 struct sigvec vec, ivec, qvec;
164 RETSIGTYPE (*istat) (), (*qstat) ();
171 #ifdef SERVER_SUPPORT
172 server_active ? "S" :
175 cvs_outerr (" -> system (", 0);
177 cvs_outerr (")\n", 0);
179 if (noexec && (flags & RUN_REALLY) == 0)
182 /* make sure that we are null terminated, since we didn't calloc */
185 /* setup default file descriptor numbers */
190 /* set the file modes for stdout and stderr */
191 mode_out = mode_err = O_WRONLY | O_CREAT;
192 mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC);
193 mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
195 if (stin && (shin = open (stin, O_RDONLY)) == -1)
198 error (0, errno, "cannot open %s for reading (prog %s)",
202 if (stout && (shout = open (stout, mode_out, 0666)) == -1)
205 error (0, errno, "cannot open %s for writing (prog %s)",
209 if (sterr && (flags & RUN_COMBINED) == 0)
211 if ((sherr = open (sterr, mode_err, 0666)) == -1)
214 error (0, errno, "cannot open %s for writing (prog %s)",
220 /* Make sure we don't flush this twice, once in the subprocess. */
224 /* The output files, if any, are now created. Do the fork and dups.
226 We use vfork not so much for a performance boost (the
227 performance boost, if any, is modest on most modern unices),
228 but for the sake of systems without a memory management unit,
229 which find it difficult or impossible to implement fork at all
230 (e.g. Amiga). The other solution is spawn (see
231 windows-NT/run.c). */
242 (void) dup2 (shin, 0);
247 (void) dup2 (shout, 1);
248 (void) close (shout);
250 if (flags & RUN_COMBINED)
254 (void) dup2 (sherr, 2);
255 (void) close (sherr);
258 #ifdef SETXID_SUPPORT
260 ** This prevents a user from creating a privileged shell
261 ** from the text editor when the SETXID_SUPPORT option is selected.
263 if (!strcmp (run_argv[0], Editor) && setegid (getgid ()))
265 error (0, errno, "cannot set egid to gid");
270 /* dup'ing is done. try to run it now */
271 (void) execvp (run_argv[0], run_argv);
272 error (0, errno, "cannot exec %s", run_argv[0]);
281 /* the parent. Ignore some signals for now */
283 if (flags & RUN_SIGIGNORE)
285 act.sa_handler = SIG_IGN;
286 (void) sigemptyset (&act.sa_mask);
288 (void) sigaction (SIGINT, &act, &iact);
289 (void) sigaction (SIGQUIT, &act, &qact);
293 (void) sigemptyset (&sigset_mask);
294 (void) sigaddset (&sigset_mask, SIGINT);
295 (void) sigaddset (&sigset_mask, SIGQUIT);
296 (void) sigprocmask (SIG_SETMASK, &sigset_mask, &sigset_omask);
300 if (flags & RUN_SIGIGNORE)
302 memset (&vec, 0, sizeof vec);
303 vec.sv_handler = SIG_IGN;
304 (void) sigvec (SIGINT, &vec, &ivec);
305 (void) sigvec (SIGQUIT, &vec, &qvec);
308 mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT));
310 istat = signal (SIGINT, SIG_IGN);
311 qstat = signal (SIGQUIT, SIG_IGN);
315 /* wait for our process to die and munge return status */
317 while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
320 while ((w = wait (&status)) != pid)
322 if (w == -1 && errno != EINTR)
332 #ifndef VMS /* status is return status */
333 else if (WIFEXITED (status))
334 rc = WEXITSTATUS (status);
335 else if (WIFSIGNALED (status))
337 if (WTERMSIG (status) == SIGPIPE)
338 error (1, 0, "broken pipe");
344 rc = WEXITSTATUS (status);
347 /* restore the signals */
349 if (flags & RUN_SIGIGNORE)
351 (void) sigaction (SIGINT, &iact, NULL);
352 (void) sigaction (SIGQUIT, &qact, NULL);
355 (void) sigprocmask (SIG_SETMASK, &sigset_omask, NULL);
358 if (flags & RUN_SIGIGNORE)
360 (void) sigvec (SIGINT, &ivec, NULL);
361 (void) sigvec (SIGQUIT, &qvec, NULL);
364 (void) sigsetmask (mask);
366 (void) signal (SIGINT, istat);
367 (void) signal (SIGQUIT, qstat);
371 /* cleanup the open file descriptors */
374 (void) close (sherr);
376 /* ensure things are received by the parent in the correct order
377 * relative to the protocol pipe
382 (void) close (shout);
384 /* ensure things are received by the parent in the correct order
385 * relative to the protocol pipe
404 void (*outfn) (const char *, size_t);
408 else if (fp == stdout)
412 error (1, 0, "internal error: bad argument to run_print");
413 /* Solely to placate gcc -Wall.
414 FIXME: it'd be better to use a function named `fatal' that
415 is known never to return. Then kludges wouldn't be necessary. */
419 for (i = 0; i < run_argc; i++)
422 (*outfn) (run_argv[i], 0);
424 if (i != run_argc - 1)
431 /* Return value is NULL for error, or if noexec was set. If there was an
432 error, return NULL and I'm not sure whether errno was set (the Red Hat
433 Linux 4.1 popen manpage was kind of vague but discouraging; and the noexec
434 case complicates this even aside from popen behavior). */
436 run_popen (const char *cmd, const char *mode)
438 TRACE (TRACE_FUNCTION, "run_popen (%s,%s)", cmd, mode);
442 return popen (cmd, mode);
447 /* Work around an OpenSSH problem: it can put its standard file
448 descriptors into nonblocking mode, which will mess us up if we
449 share file descriptions with it. The simplest workaround is
450 to create an intervening process between OpenSSH and the
454 work_around_openssh_glitch (void)
460 /* Do nothing unless stderr is a file that is affected by
462 if (!(fstat (STDERR_FILENO, &sb) == 0
463 && (S_ISFIFO (sb.st_mode) || S_ISSOCK (sb.st_mode)
464 || S_ISCHR (sb.st_mode) || S_ISBLK (sb.st_mode))))
467 if (pipe (stderr_pipe) < 0)
468 error (1, errno, "cannot create pipe");
471 error (1, errno, "cannot fork");
474 /* Still in child of original process. Act like "cat -u". */
480 if (close (stderr_pipe[1]) < 0)
481 error (1, errno, "cannot close pipe");
483 while ((inbytes = read (stderr_pipe[0], buf, sizeof buf)) != 0)
491 error (1, errno, "reading from pipe");
496 ssize_t w = write (STDERR_FILENO,
497 buf + outbytes, inbytes - outbytes);
507 while (inbytes != outbytes);
510 /* Done processing output from grandchild. Propagate
511 its exit status back to the parent. */
512 while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
515 error (1, errno, "waiting for child");
516 if (!WIFEXITED (status))
518 if (WIFSIGNALED (status))
519 raise (WTERMSIG (status));
520 error (1, errno, "child did not exit cleanly");
522 _exit (WEXITSTATUS (status));
525 /* Grandchild of original process. */
526 if (close (stderr_pipe[0]) < 0)
527 error (1, errno, "cannot close pipe");
529 if (stderr_pipe[1] != STDERR_FILENO)
531 if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
532 error (1, errno, "cannot dup2 pipe");
533 if (close (stderr_pipe[1]) < 0)
534 error (1, errno, "cannot close pipe");
541 piped_child (char *const *command, int *tofdp, int *fromfdp, bool fix_stderr)
544 int to_child_pipe[2];
545 int from_child_pipe[2];
547 if (pipe (to_child_pipe) < 0)
548 error (1, errno, "cannot create pipe");
549 if (pipe (from_child_pipe) < 0)
550 error (1, errno, "cannot create pipe");
552 #ifdef USE_SETMODE_BINARY
553 setmode (to_child_pipe[0], O_BINARY);
554 setmode (to_child_pipe[1], O_BINARY);
555 setmode (from_child_pipe[0], O_BINARY);
556 setmode (from_child_pipe[1], O_BINARY);
561 error (1, errno, "cannot fork");
564 if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0)
565 error (1, errno, "cannot dup2 pipe");
566 if (close (to_child_pipe[1]) < 0)
567 error (1, errno, "cannot close pipe");
568 if (close (from_child_pipe[0]) < 0)
569 error (1, errno, "cannot close pipe");
570 if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
571 error (1, errno, "cannot dup2 pipe");
574 work_around_openssh_glitch ();
576 /* Okay to cast out const below - execvp don't return nohow. */
577 execvp ((char *)command[0], (char **)command);
578 error (1, errno, "cannot exec %s", command[0]);
580 if (close (to_child_pipe[0]) < 0)
581 error (1, errno, "cannot close pipe");
582 if (close (from_child_pipe[1]) < 0)
583 error (1, errno, "cannot close pipe");
585 *tofdp = to_child_pipe[1];
586 *fromfdp = from_child_pipe[0];
593 run_piped (int *tofdp, int *fromfdp)
596 return piped_child (run_argv, tofdp, fromfdp, false);
602 close_on_exec (int fd)
605 if (fcntl (fd, F_SETFD, 1) == -1)
606 error (1, errno, "can't set close-on-exec flag on %d", fd);