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