summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/run.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/run.c')
-rw-r--r--contrib/cvs/src/run.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/contrib/cvs/src/run.c b/contrib/cvs/src/run.c
index 036821e..74e418d 100644
--- a/contrib/cvs/src/run.c
+++ b/contrib/cvs/src/run.c
@@ -10,11 +10,7 @@
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. */
+ GNU General Public License for more details. */
#include "cvs.h"
@@ -32,10 +28,11 @@
#endif
static void run_add_arg PROTO((const char *s));
-static void run_init_prog PROTO((void));
extern char *strtok ();
+extern int vasprintf ();
+
/*
* 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
@@ -49,7 +46,6 @@ extern char *strtok ();
* 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;
@@ -70,8 +66,7 @@ run_setup (fmt, va_alist)
#endif
char *cp;
int i;
-
- run_init_prog ();
+ char *run_prog;
/* clean out any malloc'ed values from run_argv */
for (i = 0; i < run_argc; i++)
@@ -87,15 +82,18 @@ run_setup (fmt, va_alist)
/* process the varargs into run_prog */
#ifdef HAVE_VPRINTF
VA_START (args, fmt);
- (void) vsprintf (run_prog, fmt, args);
+ (void) vasprintf (&run_prog, fmt, args);
va_end (args);
#else
- (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
+ you lose
#endif
+ if (run_prog == NULL)
+ error (1, 0, "out of memory");
/* 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);
+ free (run_prog);
}
void
@@ -119,20 +117,22 @@ run_args (fmt, va_alist)
#ifdef HAVE_VPRINTF
va_list args;
#endif
-
- run_init_prog ();
+ char *run_prog;
/* process the varargs into run_prog */
#ifdef HAVE_VPRINTF
VA_START (args, fmt);
- (void) vsprintf (run_prog, fmt, args);
+ (void) vasprintf (&run_prog, fmt, args);
va_end (args);
#else
- (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
+ you lose
#endif
+ if (run_prog == NULL)
+ error (1, 0, "out of memory");
/* and add the (single) argument to the run_argv list */
run_add_arg (run_prog);
+ free (run_prog);
}
static void
@@ -153,14 +153,6 @@ run_add_arg (s)
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;
@@ -192,12 +184,11 @@ run_exec (stin, stout, sterr, flags)
if (trace)
{
#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> system(", (server_active) ? 'S' : ' ');
-#else
- (void) fprintf (stderr, "-> system(");
+ cvs_outerr (server_active ? "S" : " ", 1);
#endif
+ cvs_outerr ("-> system(", 0);
run_print (stderr);
- (void) fprintf (stderr, ")\n");
+ cvs_outerr (")\n", 0);
}
if (noexec && (flags & RUN_REALLY) == 0)
return (0);
@@ -244,7 +235,14 @@ run_exec (stin, stout, sterr, flags)
fflush (stdout);
fflush (stderr);
- /* The output files, if any, are now created. Do the fork and dups */
+ /* The output files, if any, are now created. Do the fork and dups.
+
+ We use vfork not so much for the sake of unices without
+ copy-on-write (such systems are rare these days), but for the
+ sake of systems without an MMU, which therefore can't do
+ copy-on-write (e.g. Amiga). The other solution is spawn (see
+ windows-NT/run.c). */
+
#ifdef HAVE_VFORK
pid = vfork ();
#else
@@ -393,12 +391,22 @@ run_print (fp)
FILE *fp;
{
int i;
+ void (*outfn) PROTO ((const char *, size_t));
+
+ if (fp == stderr)
+ outfn = cvs_outerr;
+ else if (fp == stdout)
+ outfn = cvs_output;
+ else
+ error (1, 0, "internal error: bad argument to run_print");
for (i = 0; i < run_argc; i++)
{
- (void) fprintf (fp, "'%s'", run_argv[i]);
+ (*outfn) ("'", 1);
+ (*outfn) (run_argv[i], 0);
+ (*outfn) ("'", 1);
if (i != run_argc - 1)
- (void) fprintf (fp, " ");
+ (*outfn) (" ", 1);
}
}
@@ -437,7 +445,11 @@ piped_child (command, tofdp, fromfdp)
if (pipe (from_child_pipe) < 0)
error (1, errno, "cannot create pipe");
+#ifdef HAVE_VFORK
+ pid = vfork ();
+#else
pid = fork ();
+#endif
if (pid < 0)
error (1, errno, "cannot fork");
if (pid == 0)
@@ -494,7 +506,11 @@ filter_stream_through_program (oldfd, dir, prog, pidp)
if (pipe (p))
error (1, errno, "cannot create pipe");
+#ifdef HAVE_VFORK
+ newpid = vfork ();
+#else
newpid = fork ();
+#endif
if (pidp)
*pidp = newpid;
switch (newpid)
OpenPOWER on IntegriCloud