home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / src / run.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  12KB  |  550 lines

  1. /* run.c --- routines for executing subprocesses.
  2.    
  3.    This file is part of GNU CVS.
  4.  
  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
  8.    later version.
  9.  
  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.
  14.  
  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.  */
  18.  
  19. #include "cvs.h"
  20.  
  21. #ifdef HAVE_VPRINTF
  22. #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
  23. #include <stdarg.h>
  24. #define VA_START(args, lastarg) va_start(args, lastarg)
  25. #else
  26. #include <varargs.h>
  27. #define VA_START(args, lastarg) va_start(args)
  28. #endif
  29. #else
  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;
  32. #endif
  33.  
  34. static void run_add_arg PROTO((const char *s));
  35. static void run_init_prog PROTO((void));
  36.  
  37. extern char *strtok ();
  38.  
  39. /*
  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.
  44.  * 
  45.  * Then, optionally call run_arg() for each additional argument that you'd like
  46.  * to pass to the executed program.
  47.  * 
  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().
  51.  */
  52. static char *run_prog;
  53. static char **run_argv;
  54. static int run_argc;
  55. static int run_argc_allocated;
  56.  
  57. /* VARARGS */
  58. #if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
  59. void 
  60. run_setup (const char *fmt,...)
  61. #else
  62. void 
  63. run_setup (fmt, va_alist)
  64.     char *fmt;
  65.     va_dcl
  66. #endif
  67. {
  68. #ifdef HAVE_VPRINTF
  69.     va_list args;
  70. #endif
  71.     char *cp;
  72.     int i;
  73.  
  74.     run_init_prog ();
  75.  
  76.     /* clean out any malloc'ed values from run_argv */
  77.     for (i = 0; i < run_argc; i++)
  78.     {
  79.     if (run_argv[i])
  80.     {
  81.         free (run_argv[i]);
  82.         run_argv[i] = (char *) 0;
  83.     }
  84.     }
  85.     run_argc = 0;
  86.  
  87.     /* process the varargs into run_prog */
  88. #ifdef HAVE_VPRINTF
  89.     VA_START (args, fmt);
  90.     (void) vsprintf (run_prog, fmt, args);
  91.     va_end (args);
  92. #else
  93.     (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
  94. #endif
  95.  
  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"))
  98.     run_add_arg (cp);
  99. }
  100.  
  101. void
  102. run_arg (s)
  103.     const char *s;
  104. {
  105.     run_add_arg (s);
  106. }
  107.  
  108. /* VARARGS */
  109. #if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
  110. void 
  111. run_args (const char *fmt,...)
  112. #else
  113. void 
  114. run_args (fmt, va_alist)
  115.     char *fmt;
  116.     va_dcl
  117. #endif
  118. {
  119. #ifdef HAVE_VPRINTF
  120.     va_list args;
  121. #endif
  122.  
  123.     run_init_prog ();
  124.  
  125.     /* process the varargs into run_prog */
  126. #ifdef HAVE_VPRINTF
  127.     VA_START (args, fmt);
  128.     (void) vsprintf (run_prog, fmt, args);
  129.     va_end (args);
  130. #else
  131.     (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
  132. #endif
  133.  
  134.     /* and add the (single) argument to the run_argv list */
  135.     run_add_arg (run_prog);
  136. }
  137.  
  138. static void
  139. run_add_arg (s)
  140.     const char *s;
  141. {
  142.     /* allocate more argv entries if we've run out */
  143.     if (run_argc >= run_argc_allocated)
  144.     {
  145.     run_argc_allocated += 50;
  146.     run_argv = (char **) xrealloc ((char *) run_argv,
  147.                      run_argc_allocated * sizeof (char **));
  148.     }
  149.  
  150.     if (s)
  151.     run_argv[run_argc++] = xstrdup (s);
  152.     else
  153.     run_argv[run_argc] = (char *) 0;    /* not post-incremented on purpose! */
  154. }
  155.  
  156. static void
  157. run_init_prog ()
  158. {
  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 */
  162. }
  163.  
  164. int
  165. run_exec (stin, stout, sterr, flags)
  166.     char *stin;
  167.     char *stout;
  168.     char *sterr;
  169.     int flags;
  170. {
  171.     int shin, shout, sherr;
  172.     int mode_out, mode_err;
  173.     int status;
  174.     int rc = -1;
  175.     int rerrno = 0;
  176.     int pid, w;
  177.  
  178. #ifdef POSIX_SIGNALS
  179.     sigset_t sigset_mask, sigset_omask;
  180.     struct sigaction act, iact, qact;
  181.  
  182. #else
  183. #ifdef BSD_SIGNALS
  184.     int mask;
  185.     struct sigvec vec, ivec, qvec;
  186.  
  187. #else
  188.     RETSIGTYPE (*istat) (), (*qstat) ();
  189. #endif
  190. #endif
  191.  
  192.     if (trace)
  193.     {
  194. #ifdef SERVER_SUPPORT
  195.     (void) fprintf (stderr, "%c-> system(", (server_active) ? 'S' : ' ');
  196. #else
  197.     (void) fprintf (stderr, "-> system(");
  198. #endif
  199.     run_print (stderr);
  200.     (void) fprintf (stderr, ")\n");
  201.     }
  202.     if (noexec && (flags & RUN_REALLY) == 0)
  203.     return (0);
  204.  
  205.     /* make sure that we are null terminated, since we didn't calloc */
  206.     run_add_arg ((char *) 0);
  207.  
  208.     /* setup default file descriptor numbers */
  209.     shin = 0;
  210.     shout = 1;
  211.     sherr = 2;
  212.  
  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);
  217.  
  218.     if (stin && (shin = open (stin, O_RDONLY)) == -1)
  219.     {
  220.     rerrno = errno;
  221.     error (0, errno, "cannot open %s for reading (prog %s)",
  222.            stin, run_argv[0]);
  223.     goto out0;
  224.     }
  225.     if (stout && (shout = open (stout, mode_out, 0666)) == -1)
  226.     {
  227.     rerrno = errno;
  228.     error (0, errno, "cannot open %s for writing (prog %s)",
  229.            stout, run_argv[0]);
  230.     goto out1;
  231.     }
  232.     if (sterr && (flags & RUN_COMBINED) == 0)
  233.     {
  234.     if ((sherr = open (sterr, mode_err, 0666)) == -1)
  235.     {
  236.         rerrno = errno;
  237.         error (0, errno, "cannot open %s for writing (prog %s)",
  238.            sterr, run_argv[0]);
  239.         goto out2;
  240.     }
  241.     }
  242.  
  243.     /* Make sure we don't flush this twice, once in the subprocess.  */
  244.     fflush (stdout);
  245.     fflush (stderr);
  246.  
  247.     /* The output files, if any, are now created.  Do the fork and dups */
  248. #ifdef HAVE_VFORK
  249.     pid = vfork ();
  250. #else
  251.     pid = fork ();
  252. #endif
  253.     if (pid == 0)
  254.     {
  255.     if (shin != 0)
  256.     {
  257.         (void) dup2 (shin, 0);
  258.         (void) close (shin);
  259.     }
  260.     if (shout != 1)
  261.     {
  262.         (void) dup2 (shout, 1);
  263.         (void) close (shout);
  264.     }
  265.     if (flags & RUN_COMBINED)
  266.         (void) dup2 (1, 2);
  267.     else if (sherr != 2)
  268.     {
  269.         (void) dup2 (sherr, 2);
  270.         (void) close (sherr);
  271.     }
  272.  
  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]);
  276.     _exit (127);
  277.     }
  278.     else if (pid == -1)
  279.     {
  280.     rerrno = errno;
  281.     goto out;
  282.     }
  283.  
  284.     /* the parent.  Ignore some signals for now */
  285. #ifdef POSIX_SIGNALS
  286.     if (flags & RUN_SIGIGNORE)
  287.     {
  288.     act.sa_handler = SIG_IGN;
  289.     (void) sigemptyset (&act.sa_mask);
  290.     act.sa_flags = 0;
  291.     (void) sigaction (SIGINT, &act, &iact);
  292.     (void) sigaction (SIGQUIT, &act, &qact);
  293.     }
  294.     else
  295.     {
  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);
  300.     }
  301. #else
  302. #ifdef BSD_SIGNALS
  303.     if (flags & RUN_SIGIGNORE)
  304.     {
  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);
  309.     }
  310.     else
  311.     mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT));
  312. #else
  313.     istat = signal (SIGINT, SIG_IGN);
  314.     qstat = signal (SIGQUIT, SIG_IGN);
  315. #endif
  316. #endif
  317.  
  318.     /* wait for our process to die and munge return status */
  319. #ifdef POSIX_SIGNALS
  320.     while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
  321.     ;
  322. #else
  323.     while ((w = wait (&status)) != pid)
  324.     {
  325.     if (w == -1 && errno != EINTR)
  326.         break;
  327.     }
  328. #endif
  329.  
  330.     if (w == -1)
  331.     {
  332.     rc = -1;
  333.     rerrno = errno;
  334.     }
  335. #ifndef VMS /* status is return status */
  336.     else if (WIFEXITED (status))
  337.     rc = WEXITSTATUS (status);
  338.     else if (WIFSIGNALED (status))
  339.     {
  340.     if (WTERMSIG (status) == SIGPIPE)
  341.         error (1, 0, "broken pipe");
  342.     rc = 2;
  343.     }
  344.     else
  345.     rc = 1;
  346. #else /* VMS */
  347.     rc = WEXITSTATUS (status);
  348. #endif /* VMS */
  349.  
  350.     /* restore the signals */
  351. #ifdef POSIX_SIGNALS
  352.     if (flags & RUN_SIGIGNORE)
  353.     {
  354.     (void) sigaction (SIGINT, &iact, (struct sigaction *) NULL);
  355.     (void) sigaction (SIGQUIT, &qact, (struct sigaction *) NULL);
  356.     }
  357.     else
  358.     (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *) NULL);
  359. #else
  360. #ifdef BSD_SIGNALS
  361.     if (flags & RUN_SIGIGNORE)
  362.     {
  363.     (void) sigvec (SIGINT, &ivec, (struct sigvec *) NULL);
  364.     (void) sigvec (SIGQUIT, &qvec, (struct sigvec *) NULL);
  365.     }
  366.     else
  367.     (void) sigsetmask (mask);
  368. #else
  369.     (void) signal (SIGINT, istat);
  370.     (void) signal (SIGQUIT, qstat);
  371. #endif
  372. #endif
  373.  
  374.     /* cleanup the open file descriptors */
  375.   out:
  376.     if (sterr)
  377.     (void) close (sherr);
  378.   out2:
  379.     if (stout)
  380.     (void) close (shout);
  381.   out1:
  382.     if (stin)
  383.     (void) close (shin);
  384.  
  385.   out0:
  386.     if (rerrno)
  387.     errno = rerrno;
  388.     return (rc);
  389. }
  390.  
  391. void
  392. run_print (fp)
  393.     FILE *fp;
  394. {
  395.     int i;
  396.  
  397.     for (i = 0; i < run_argc; i++)
  398.     {
  399.     (void) fprintf (fp, "'%s'", run_argv[i]);
  400.     if (i != run_argc - 1)
  401.         (void) fprintf (fp, " ");
  402.     }
  403. }
  404.  
  405. FILE *
  406. run_popen (cmd, mode)
  407.     const char *cmd;
  408.     const char *mode;
  409. {
  410.     if (trace)
  411. #ifdef SERVER_SUPPORT
  412.     (void) fprintf (stderr, "%c-> run_popen(%s,%s)\n",
  413.             (server_active) ? 'S' : ' ', cmd, mode);
  414. #else
  415.     (void) fprintf (stderr, "-> run_popen(%s,%s)\n", cmd, mode);
  416. #endif
  417.     if (noexec)
  418.     return (NULL);
  419.  
  420.     return (popen (cmd, mode));
  421. }
  422.  
  423. extern int evecvp PROTO((char *file, char **argv));
  424.  
  425. int
  426. piped_child (command, tofdp, fromfdp)
  427.      char **command;
  428.      int *tofdp;
  429.      int *fromfdp;
  430. {
  431.     int pid;
  432.     int to_child_pipe[2];
  433.     int from_child_pipe[2];
  434.  
  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");
  439.  
  440. #ifdef HAVE_VFORK
  441.     pid = vfork ();
  442. #else
  443.     pid = fork ();
  444. #endif
  445.     if (pid < 0)
  446.     error (1, errno, "cannot fork");
  447.     if (pid == 0)
  448.     {
  449.     if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0)
  450.         error (1, errno, "cannot dup2");
  451.     if (close (to_child_pipe[1]) < 0)
  452.         error (1, errno, "cannot close");
  453.     if (close (from_child_pipe[0]) < 0)
  454.         error (1, errno, "cannot close");
  455.     if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
  456.         error (1, errno, "cannot dup2");
  457.  
  458.     execvp (command[0], command);
  459.     error (1, errno, "cannot exec");
  460.     }
  461.     if (close (to_child_pipe[0]) < 0)
  462.     error (1, errno, "cannot close");
  463.     if (close (from_child_pipe[1]) < 0)
  464.     error (1, errno, "cannot close");
  465.  
  466.     *tofdp = to_child_pipe[1];
  467.     *fromfdp = from_child_pipe[0];
  468.     return pid;
  469. }
  470.  
  471.  
  472. void
  473. close_on_exec (fd)
  474.      int fd;
  475. {
  476. #if defined (FD_CLOEXEC) && defined (F_SETFD)
  477.   if (fcntl (fd, F_SETFD, 1))
  478.     error (1, errno, "can't set close-on-exec flag on %d", fd);
  479. #endif
  480. }
  481.  
  482. /*
  483.  * dir = 0 : main proc writes to new proc, which writes to oldfd
  484.  * dir = 1 : main proc reads from new proc, which reads from oldfd
  485.  *
  486.  * Returns: a file descriptor.  On failure (i.e., the exec fails),
  487.  * then filter_stream_through_program() complains and dies.
  488.  */
  489.  
  490. int
  491. filter_stream_through_program (oldfd, dir, prog, pidp)
  492.      int oldfd, dir;
  493.      char **prog;
  494.      pid_t *pidp;
  495. {
  496.     int p[2], newfd;
  497.     pid_t newpid;
  498.  
  499.     if (pipe (p))
  500.     error (1, errno, "cannot create pipe");
  501. #ifdef HAVE_VFORK
  502.     newpid = vfork ();
  503. #else
  504.     newpid = fork ();
  505. #endif
  506.     if (pidp)
  507.     *pidp = newpid;
  508.     switch (newpid)
  509.     {
  510.       case -1:
  511.     error (1, errno, "cannot fork");
  512.       case 0:
  513.     /* child */
  514.     if (dir)
  515.     {
  516.         /* write to new pipe */
  517.         close (p[0]);
  518.         dup2 (oldfd, 0);
  519.         dup2 (p[1], 1);
  520.     }
  521.     else
  522.     {
  523.         /* read from new pipe */
  524.         close (p[1]);
  525.         dup2 (p[0], 0);
  526.         dup2 (oldfd, 1);
  527.     }
  528.     /* Should I be blocking some signals here?  */
  529.     execvp (prog[0], prog);
  530.     error (1, errno, "couldn't exec %s", prog[0]);
  531.       default:
  532.     /* parent */
  533.     close (oldfd);
  534.     if (dir)
  535.     {
  536.         /* read from new pipe */
  537.         close (p[1]);
  538.         newfd = p[0];
  539.     }
  540.     else
  541.     {
  542.         /* write to new pipe */
  543.         close (p[0]);
  544.         newfd = p[1];
  545.     }
  546.     close_on_exec (newfd);
  547.     return newfd;
  548.     }
  549. }
  550.