run.c revision 54427
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#ifndef HAVE_UNISTD_H 18extern int execvp PROTO((char *file, char **argv)); 19#endif 20 21static void run_add_arg PROTO((const char *s)); 22 23extern char *strtok (); 24 25/* 26 * To exec a program under CVS, first call run_setup() to setup initial 27 * arguments. The argument to run_setup will be parsed into whitespace 28 * separated words and added to the global run_argv list. 29 * 30 * Then, optionally call run_arg() for each additional argument that you'd like 31 * to pass to the executed program. 32 * 33 * Finally, call run_exec() to execute the program with the specified arguments. 34 * The execvp() syscall will be used, so that the PATH is searched correctly. 35 * File redirections can be performed in the call to run_exec(). 36 */ 37static char **run_argv; 38static int run_argc; 39static int run_argc_allocated; 40 41/* VARARGS */ 42void 43run_setup (prog) 44 const char *prog; 45{ 46 char *cp; 47 int i; 48 char *run_prog; 49 50 /* clean out any malloc'ed values from run_argv */ 51 for (i = 0; i < run_argc; i++) 52 { 53 if (run_argv[i]) 54 { 55 free (run_argv[i]); 56 run_argv[i] = (char *) 0; 57 } 58 } 59 run_argc = 0; 60 61 run_prog = xstrdup (prog); 62 63 /* put each word into run_argv, allocating it as we go */ 64 for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t")) 65 run_add_arg (cp); 66 free (run_prog); 67} 68 69void 70run_arg (s) 71 const char *s; 72{ 73 run_add_arg (s); 74} 75 76static void 77run_add_arg (s) 78 const char *s; 79{ 80 /* allocate more argv entries if we've run out */ 81 if (run_argc >= run_argc_allocated) 82 { 83 run_argc_allocated += 50; 84 run_argv = (char **) xrealloc ((char *) run_argv, 85 run_argc_allocated * sizeof (char **)); 86 } 87 88 if (s) 89 run_argv[run_argc++] = xstrdup (s); 90 else 91 run_argv[run_argc] = (char *) 0; /* not post-incremented on purpose! */ 92} 93 94int 95run_exec (stin, stout, sterr, flags) 96 const char *stin; 97 const char *stout; 98 const char *sterr; 99 int flags; 100{ 101 int shin, shout, sherr; 102 int mode_out, mode_err; 103 int status; 104 int rc = -1; 105 int rerrno = 0; 106 int pid, w; 107 108#ifdef POSIX_SIGNALS 109 sigset_t sigset_mask, sigset_omask; 110 struct sigaction act, iact, qact; 111 112#else 113#ifdef BSD_SIGNALS 114 int mask; 115 struct sigvec vec, ivec, qvec; 116 117#else 118 RETSIGTYPE (*istat) (), (*qstat) (); 119#endif 120#endif 121 122 if (trace) 123 { 124#ifdef SERVER_SUPPORT 125 cvs_outerr (server_active ? "S" : " ", 1); 126#endif 127 cvs_outerr ("-> system(", 0); 128 run_print (stderr); 129 cvs_outerr (")\n", 0); 130 } 131 if (noexec && (flags & RUN_REALLY) == 0) 132 return (0); 133 134 /* make sure that we are null terminated, since we didn't calloc */ 135 run_add_arg ((char *) 0); 136 137 /* setup default file descriptor numbers */ 138 shin = 0; 139 shout = 1; 140 sherr = 2; 141 142 /* set the file modes for stdout and stderr */ 143 mode_out = mode_err = O_WRONLY | O_CREAT; 144 mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC); 145 mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC); 146 147 if (stin && (shin = open (stin, O_RDONLY)) == -1) 148 { 149 rerrno = errno; 150 error (0, errno, "cannot open %s for reading (prog %s)", 151 stin, run_argv[0]); 152 goto out0; 153 } 154 if (stout && (shout = open (stout, mode_out, 0666)) == -1) 155 { 156 rerrno = errno; 157 error (0, errno, "cannot open %s for writing (prog %s)", 158 stout, run_argv[0]); 159 goto out1; 160 } 161 if (sterr && (flags & RUN_COMBINED) == 0) 162 { 163 if ((sherr = open (sterr, mode_err, 0666)) == -1) 164 { 165 rerrno = errno; 166 error (0, errno, "cannot open %s for writing (prog %s)", 167 sterr, run_argv[0]); 168 goto out2; 169 } 170 } 171 172 /* Make sure we don't flush this twice, once in the subprocess. */ 173 fflush (stdout); 174 fflush (stderr); 175 176 /* The output files, if any, are now created. Do the fork and dups. 177 178 We use vfork not so much for a performance boost (the 179 performance boost, if any, is modest on most modern unices), 180 but for the sake of systems without a memory management unit, 181 which find it difficult or impossible to implement fork at all 182 (e.g. Amiga). The other solution is spawn (see 183 windows-NT/run.c). */ 184 185#ifdef HAVE_VFORK 186 pid = vfork (); 187#else 188 pid = fork (); 189#endif 190 if (pid == 0) 191 { 192 if (shin != 0) 193 { 194 (void) dup2 (shin, 0); 195 (void) close (shin); 196 } 197 if (shout != 1) 198 { 199 (void) dup2 (shout, 1); 200 (void) close (shout); 201 } 202 if (flags & RUN_COMBINED) 203 (void) dup2 (1, 2); 204 else if (sherr != 2) 205 { 206 (void) dup2 (sherr, 2); 207 (void) close (sherr); 208 } 209 210 /* dup'ing is done. try to run it now */ 211 (void) execvp (run_argv[0], run_argv); 212 error (0, errno, "cannot exec %s", run_argv[0]); 213 _exit (127); 214 } 215 else if (pid == -1) 216 { 217 rerrno = errno; 218 goto out; 219 } 220 221 /* the parent. Ignore some signals for now */ 222#ifdef POSIX_SIGNALS 223 if (flags & RUN_SIGIGNORE) 224 { 225 act.sa_handler = SIG_IGN; 226 (void) sigemptyset (&act.sa_mask); 227 act.sa_flags = 0; 228 (void) sigaction (SIGINT, &act, &iact); 229 (void) sigaction (SIGQUIT, &act, &qact); 230 } 231 else 232 { 233 (void) sigemptyset (&sigset_mask); 234 (void) sigaddset (&sigset_mask, SIGINT); 235 (void) sigaddset (&sigset_mask, SIGQUIT); 236 (void) sigprocmask (SIG_SETMASK, &sigset_mask, &sigset_omask); 237 } 238#else 239#ifdef BSD_SIGNALS 240 if (flags & RUN_SIGIGNORE) 241 { 242 memset ((char *) &vec, 0, sizeof (vec)); 243 vec.sv_handler = SIG_IGN; 244 (void) sigvec (SIGINT, &vec, &ivec); 245 (void) sigvec (SIGQUIT, &vec, &qvec); 246 } 247 else 248 mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT)); 249#else 250 istat = signal (SIGINT, SIG_IGN); 251 qstat = signal (SIGQUIT, SIG_IGN); 252#endif 253#endif 254 255 /* wait for our process to die and munge return status */ 256#ifdef POSIX_SIGNALS 257 while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR) 258 ; 259#else 260 while ((w = wait (&status)) != pid) 261 { 262 if (w == -1 && errno != EINTR) 263 break; 264 } 265#endif 266 267 if (w == -1) 268 { 269 rc = -1; 270 rerrno = errno; 271 } 272#ifndef VMS /* status is return status */ 273 else if (WIFEXITED (status)) 274 rc = WEXITSTATUS (status); 275 else if (WIFSIGNALED (status)) 276 { 277 if (WTERMSIG (status) == SIGPIPE) 278 error (1, 0, "broken pipe"); 279 rc = 2; 280 } 281 else 282 rc = 1; 283#else /* VMS */ 284 rc = WEXITSTATUS (status); 285#endif /* VMS */ 286 287 /* restore the signals */ 288#ifdef POSIX_SIGNALS 289 if (flags & RUN_SIGIGNORE) 290 { 291 (void) sigaction (SIGINT, &iact, (struct sigaction *) NULL); 292 (void) sigaction (SIGQUIT, &qact, (struct sigaction *) NULL); 293 } 294 else 295 (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *) NULL); 296#else 297#ifdef BSD_SIGNALS 298 if (flags & RUN_SIGIGNORE) 299 { 300 (void) sigvec (SIGINT, &ivec, (struct sigvec *) NULL); 301 (void) sigvec (SIGQUIT, &qvec, (struct sigvec *) NULL); 302 } 303 else 304 (void) sigsetmask (mask); 305#else 306 (void) signal (SIGINT, istat); 307 (void) signal (SIGQUIT, qstat); 308#endif 309#endif 310 311 /* cleanup the open file descriptors */ 312 out: 313 if (sterr) 314 (void) close (sherr); 315 out2: 316 if (stout) 317 (void) close (shout); 318 out1: 319 if (stin) 320 (void) close (shin); 321 322 out0: 323 if (rerrno) 324 errno = rerrno; 325 return (rc); 326} 327 328void 329run_print (fp) 330 FILE *fp; 331{ 332 int i; 333 void (*outfn) PROTO ((const char *, size_t)); 334 335 if (fp == stderr) 336 outfn = cvs_outerr; 337 else if (fp == stdout) 338 outfn = cvs_output; 339 else 340 { 341 error (1, 0, "internal error: bad argument to run_print"); 342 /* Solely to placate gcc -Wall. 343 FIXME: it'd be better to use a function named `fatal' that 344 is known never to return. Then kludges wouldn't be necessary. */ 345 outfn = NULL; 346 } 347 348 for (i = 0; i < run_argc; i++) 349 { 350 (*outfn) ("'", 1); 351 (*outfn) (run_argv[i], 0); 352 (*outfn) ("'", 1); 353 if (i != run_argc - 1) 354 (*outfn) (" ", 1); 355 } 356} 357 358/* Return value is NULL for error, or if noexec was set. If there was an 359 error, return NULL and I'm not sure whether errno was set (the Red Hat 360 Linux 4.1 popen manpage was kind of vague but discouraging; and the noexec 361 case complicates this even aside from popen behavior). */ 362 363FILE * 364run_popen (cmd, mode) 365 const char *cmd; 366 const char *mode; 367{ 368 if (trace) 369 (void) fprintf (stderr, "%s-> run_popen(%s,%s)\n", 370 CLIENT_SERVER_STR, cmd, mode); 371 if (noexec) 372 return (NULL); 373 374 return (popen (cmd, mode)); 375} 376 377int 378piped_child (command, tofdp, fromfdp) 379 char **command; 380 int *tofdp; 381 int *fromfdp; 382{ 383 int pid; 384 int to_child_pipe[2]; 385 int from_child_pipe[2]; 386 387 if (pipe (to_child_pipe) < 0) 388 error (1, errno, "cannot create pipe"); 389 if (pipe (from_child_pipe) < 0) 390 error (1, errno, "cannot create pipe"); 391 392#ifdef USE_SETMODE_BINARY 393 setmode (to_child_pipe[0], O_BINARY); 394 setmode (to_child_pipe[1], O_BINARY); 395 setmode (from_child_pipe[0], O_BINARY); 396 setmode (from_child_pipe[1], O_BINARY); 397#endif 398 399#ifdef HAVE_VFORK 400 pid = vfork (); 401#else 402 pid = fork (); 403#endif 404 if (pid < 0) 405 error (1, errno, "cannot fork"); 406 if (pid == 0) 407 { 408 if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0) 409 error (1, errno, "cannot dup2 pipe"); 410 if (close (to_child_pipe[1]) < 0) 411 error (1, errno, "cannot close pipe"); 412 if (close (from_child_pipe[0]) < 0) 413 error (1, errno, "cannot close pipe"); 414 if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0) 415 error (1, errno, "cannot dup2 pipe"); 416 417 execvp (command[0], command); 418 error (1, errno, "cannot exec %s", command[0]); 419 } 420 if (close (to_child_pipe[0]) < 0) 421 error (1, errno, "cannot close pipe"); 422 if (close (from_child_pipe[1]) < 0) 423 error (1, errno, "cannot close pipe"); 424 425 *tofdp = to_child_pipe[1]; 426 *fromfdp = from_child_pipe[0]; 427 return pid; 428} 429 430 431void 432close_on_exec (fd) 433 int fd; 434{ 435#if defined (FD_CLOEXEC) && defined (F_SETFD) 436 if (fcntl (fd, F_SETFD, 1)) 437 error (1, errno, "can't set close-on-exec flag on %d", fd); 438#endif 439} 440