summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cvs/lib/run.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/cvs/lib/run.c')
-rw-r--r--gnu/usr.bin/cvs/lib/run.c533
1 files changed, 0 insertions, 533 deletions
diff --git a/gnu/usr.bin/cvs/lib/run.c b/gnu/usr.bin/cvs/lib/run.c
deleted file mode 100644
index 6a06a38..0000000
--- a/gnu/usr.bin/cvs/lib/run.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* run.c --- routines for executing subprocesses.
-
- This file is part of GNU CVS.
-
- GNU CVS is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "cvs.h"
-
-#ifdef HAVE_VPRINTF
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#include <stdarg.h>
-#define VA_START(args, lastarg) va_start(args, lastarg)
-#else
-#include <varargs.h>
-#define VA_START(args, lastarg) va_start(args)
-#endif
-#else
-#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
-#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
-#endif
-
-static void run_add_arg PROTO((const char *s));
-static void run_init_prog PROTO((void));
-
-extern char *strtok ();
-
-/*
- * To exec a program under CVS, first call run_setup() to setup any initial
- * arguments. The options to run_setup are essentially like printf(). The
- * arguments will be parsed into whitespace separated words and added to the
- * global run_argv list.
- *
- * Then, optionally call run_arg() for each additional argument that you'd like
- * to pass to the executed program.
- *
- * Finally, call run_exec() to execute the program with the specified arguments.
- * The execvp() syscall will be used, so that the PATH is searched correctly.
- * File redirections can be performed in the call to run_exec().
- */
-static char *run_prog;
-static char **run_argv;
-static int run_argc;
-static int run_argc_allocated;
-
-/* VARARGS */
-#if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
-void
-run_setup (const char *fmt,...)
-#else
-void
-run_setup (fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
-#ifdef HAVE_VPRINTF
- va_list args;
-#endif
- char *cp;
- int i;
-
- run_init_prog ();
-
- /* clean out any malloc'ed values from run_argv */
- for (i = 0; i < run_argc; i++)
- {
- if (run_argv[i])
- {
- free (run_argv[i]);
- run_argv[i] = (char *) 0;
- }
- }
- run_argc = 0;
-
- /* process the varargs into run_prog */
-#ifdef HAVE_VPRINTF
- VA_START (args, fmt);
- (void) vsprintf (run_prog, fmt, args);
- va_end (args);
-#else
- (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
-
- /* put each word into run_argv, allocating it as we go */
- for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
- run_add_arg (cp);
-}
-
-void
-run_arg (s)
- const char *s;
-{
- run_add_arg (s);
-}
-
-/* VARARGS */
-#if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
-void
-run_args (const char *fmt,...)
-#else
-void
-run_args (fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
-#ifdef HAVE_VPRINTF
- va_list args;
-#endif
-
- run_init_prog ();
-
- /* process the varargs into run_prog */
-#ifdef HAVE_VPRINTF
- VA_START (args, fmt);
- (void) vsprintf (run_prog, fmt, args);
- va_end (args);
-#else
- (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
-
- /* and add the (single) argument to the run_argv list */
- run_add_arg (run_prog);
-}
-
-static void
-run_add_arg (s)
- const char *s;
-{
- /* allocate more argv entries if we've run out */
- if (run_argc >= run_argc_allocated)
- {
- run_argc_allocated += 50;
- run_argv = (char **) xrealloc ((char *) run_argv,
- run_argc_allocated * sizeof (char **));
- }
-
- if (s)
- run_argv[run_argc++] = xstrdup (s);
- else
- run_argv[run_argc] = (char *) 0; /* not post-incremented on purpose! */
-}
-
-static void
-run_init_prog ()
-{
- /* make sure that run_prog is allocated once */
- if (run_prog == (char *) 0)
- run_prog = xmalloc (10 * 1024); /* 10K of args for _setup and _arg */
-}
-
-int
-run_exec (stin, stout, sterr, flags)
- char *stin;
- char *stout;
- char *sterr;
- int flags;
-{
- int shin, shout, sherr;
- int mode_out, mode_err;
- int status;
- int rc = -1;
- int rerrno = 0;
- int pid, w;
-
-#ifdef POSIX_SIGNALS
- sigset_t sigset_mask, sigset_omask;
- struct sigaction act, iact, qact;
-
-#else
-#ifdef BSD_SIGNALS
- int mask;
- struct sigvec vec, ivec, qvec;
-
-#else
- RETSIGTYPE (*istat) (), (*qstat) ();
-#endif
-#endif
-
- if (trace)
- {
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> system(", (server_active) ? 'S' : ' ');
-#else
- (void) fprintf (stderr, "-> system(");
-#endif
- run_print (stderr);
- (void) fprintf (stderr, ")\n");
- }
- if (noexec && (flags & RUN_REALLY) == 0)
- return (0);
-
- /* make sure that we are null terminated, since we didn't calloc */
- run_add_arg ((char *) 0);
-
- /* setup default file descriptor numbers */
- shin = 0;
- shout = 1;
- sherr = 2;
-
- /* set the file modes for stdout and stderr */
- mode_out = mode_err = O_WRONLY | O_CREAT;
- mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC);
- mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
-
- if (stin && (shin = open (stin, O_RDONLY)) == -1)
- {
- rerrno = errno;
- error (0, errno, "cannot open %s for reading (prog %s)",
- stin, run_argv[0]);
- goto out0;
- }
- if (stout && (shout = open (stout, mode_out, 0666)) == -1)
- {
- rerrno = errno;
- error (0, errno, "cannot open %s for writing (prog %s)",
- stout, run_argv[0]);
- goto out1;
- }
- if (sterr && (flags & RUN_COMBINED) == 0)
- {
- if ((sherr = open (sterr, mode_err, 0666)) == -1)
- {
- rerrno = errno;
- error (0, errno, "cannot open %s for writing (prog %s)",
- sterr, run_argv[0]);
- goto out2;
- }
- }
-
- /* Make sure we don't flush this twice, once in the subprocess. */
- fflush (stdout);
- fflush (stderr);
-
- /* The output files, if any, are now created. Do the fork and dups */
-#ifdef HAVE_VFORK
- pid = vfork ();
-#else
- pid = fork ();
-#endif
- if (pid == 0)
- {
- if (shin != 0)
- {
- (void) dup2 (shin, 0);
- (void) close (shin);
- }
- if (shout != 1)
- {
- (void) dup2 (shout, 1);
- (void) close (shout);
- }
- if (flags & RUN_COMBINED)
- (void) dup2 (1, 2);
- else if (sherr != 2)
- {
- (void) dup2 (sherr, 2);
- (void) close (sherr);
- }
-
- /* dup'ing is done. try to run it now */
- (void) execvp (run_argv[0], run_argv);
- error (0, errno, "cannot exec %s", run_argv[0]);
- _exit (127);
- }
- else if (pid == -1)
- {
- rerrno = errno;
- goto out;
- }
-
- /* the parent. Ignore some signals for now */
-#ifdef POSIX_SIGNALS
- if (flags & RUN_SIGIGNORE)
- {
- act.sa_handler = SIG_IGN;
- (void) sigemptyset (&act.sa_mask);
- act.sa_flags = 0;
- (void) sigaction (SIGINT, &act, &iact);
- (void) sigaction (SIGQUIT, &act, &qact);
- }
- else
- {
- (void) sigemptyset (&sigset_mask);
- (void) sigaddset (&sigset_mask, SIGINT);
- (void) sigaddset (&sigset_mask, SIGQUIT);
- (void) sigprocmask (SIG_SETMASK, &sigset_mask, &sigset_omask);
- }
-#else
-#ifdef BSD_SIGNALS
- if (flags & RUN_SIGIGNORE)
- {
- memset ((char *) &vec, 0, sizeof (vec));
- vec.sv_handler = SIG_IGN;
- (void) sigvec (SIGINT, &vec, &ivec);
- (void) sigvec (SIGQUIT, &vec, &qvec);
- }
- else
- mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT));
-#else
- istat = signal (SIGINT, SIG_IGN);
- qstat = signal (SIGQUIT, SIG_IGN);
-#endif
-#endif
-
- /* wait for our process to die and munge return status */
-#ifdef POSIX_SIGNALS
- while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
- ;
-#else
- while ((w = wait (&status)) != pid)
- {
- if (w == -1 && errno != EINTR)
- break;
- }
-#endif
- if (w == -1)
- {
- rc = -1;
- rerrno = errno;
- }
- else if (WIFEXITED (status))
- rc = WEXITSTATUS (status);
- else if (WIFSIGNALED (status))
- {
- if (WTERMSIG (status) == SIGPIPE)
- error (1, 0, "broken pipe");
- rc = 2;
- }
- else
- rc = 1;
-
- /* restore the signals */
-#ifdef POSIX_SIGNALS
- if (flags & RUN_SIGIGNORE)
- {
- (void) sigaction (SIGINT, &iact, (struct sigaction *) NULL);
- (void) sigaction (SIGQUIT, &qact, (struct sigaction *) NULL);
- }
- else
- (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *) NULL);
-#else
-#ifdef BSD_SIGNALS
- if (flags & RUN_SIGIGNORE)
- {
- (void) sigvec (SIGINT, &ivec, (struct sigvec *) NULL);
- (void) sigvec (SIGQUIT, &qvec, (struct sigvec *) NULL);
- }
- else
- (void) sigsetmask (mask);
-#else
- (void) signal (SIGINT, istat);
- (void) signal (SIGQUIT, qstat);
-#endif
-#endif
-
- /* cleanup the open file descriptors */
- out:
- if (sterr)
- (void) close (sherr);
- out2:
- if (stout)
- (void) close (shout);
- out1:
- if (stin)
- (void) close (shin);
-
- out0:
- if (rerrno)
- errno = rerrno;
- return (rc);
-}
-
-void
-run_print (fp)
- FILE *fp;
-{
- int i;
-
- for (i = 0; i < run_argc; i++)
- {
- (void) fprintf (fp, "'%s'", run_argv[i]);
- if (i != run_argc - 1)
- (void) fprintf (fp, " ");
- }
-}
-
-FILE *
-Popen (cmd, mode)
- const char *cmd;
- const char *mode;
-{
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> Popen(%s,%s)\n",
- (server_active) ? 'S' : ' ', cmd, mode);
-#else
- (void) fprintf (stderr, "-> Popen(%s,%s)\n", cmd, mode);
-#endif
- if (noexec)
- return (NULL);
-
- return (popen (cmd, mode));
-}
-
-extern int evecvp PROTO((char *file, char **argv));
-
-int
-piped_child (command, tofdp, fromfdp)
- char **command;
- int *tofdp;
- int *fromfdp;
-{
- int pid;
- int to_child_pipe[2];
- int from_child_pipe[2];
-
- if (pipe (to_child_pipe) < 0)
- error (1, errno, "cannot create pipe");
- if (pipe (from_child_pipe) < 0)
- error (1, errno, "cannot create pipe");
-
- pid = fork ();
- if (pid < 0)
- error (1, errno, "cannot fork");
- if (pid == 0)
- {
- if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0)
- error (1, errno, "cannot dup2");
- if (close (to_child_pipe[1]) < 0)
- error (1, errno, "cannot close");
- if (close (from_child_pipe[0]) < 0)
- error (1, errno, "cannot close");
- if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
- error (1, errno, "cannot dup2");
-
- execvp (command[0], command);
- error (1, errno, "cannot exec");
- }
- if (close (to_child_pipe[0]) < 0)
- error (1, errno, "cannot close");
- if (close (from_child_pipe[1]) < 0)
- error (1, errno, "cannot close");
-
- *tofdp = to_child_pipe[1];
- *fromfdp = from_child_pipe[0];
- return pid;
-}
-
-
-void
-close_on_exec (fd)
- int fd;
-{
-#if defined (FD_CLOEXEC) && defined (F_SETFD)
- if (fcntl (fd, F_SETFD, 1))
- error (1, errno, "can't set close-on-exec flag on %d", fd);
-#endif
-}
-
-/*
- * dir = 0 : main proc writes to new proc, which writes to oldfd
- * dir = 1 : main proc reads from new proc, which reads from oldfd
- */
-
-int
-filter_stream_through_program (oldfd, dir, prog, pidp)
- int oldfd, dir;
- char **prog;
- pid_t *pidp;
-{
- int p[2], newfd;
- pid_t newpid;
-
- if (pipe (p))
- error (1, errno, "cannot create pipe");
- newpid = fork ();
- if (pidp)
- *pidp = newpid;
- switch (newpid)
- {
- case -1:
- error (1, errno, "cannot fork");
- case 0:
- /* child */
- if (dir)
- {
- /* write to new pipe */
- close (p[0]);
- dup2 (oldfd, 0);
- dup2 (p[1], 1);
- }
- else
- {
- /* read from new pipe */
- close (p[1]);
- dup2 (p[0], 0);
- dup2 (oldfd, 1);
- }
- /* Should I be blocking some signals here? */
- execvp (prog[0], prog);
- error (1, errno, "couldn't exec %s", prog[0]);
- default:
- /* parent */
- close (oldfd);
- if (dir)
- {
- /* read from new pipe */
- close (p[1]);
- newfd = p[0];
- }
- else
- {
- /* write to new pipe */
- close (p[0]);
- newfd = p[1];
- }
- close_on_exec (newfd);
- return newfd;
- }
-}
OpenPOWER on IntegriCloud