xref: /openbsd/gnu/usr.bin/cvs/windows-NT/run.c (revision 76d0caae)
1 /* run.c --- routines for executing subprocesses under Windows NT.
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 #define WIN32_LEAN_AND_MEAN
18 #include <windows.h>
19 #include <stdlib.h>
20 #include <process.h>
21 #include <errno.h>
22 #include <io.h>
23 #include <fcntl.h>
24 
25 static void run_add_arg PROTO((const char *s));
26 static void run_init_prog PROTO((void));
27 
28 extern char *strtok ();
29 
30 /*
31  * To exec a program under CVS, first call run_setup() to setup any initial
32  * arguments.  The options to run_setup are essentially like printf(). The
33  * arguments will be parsed into whitespace separated words and added to the
34  * global run_argv list.
35  *
36  * Then, optionally call run_arg() for each additional argument that you'd like
37  * to pass to the executed program.
38  *
39  * Finally, call run_exec() to execute the program with the specified arguments.
40  * The execvp() syscall will be used, so that the PATH is searched correctly.
41  * File redirections can be performed in the call to run_exec().
42  */
43 static char **run_argv;
44 static int run_argc;
45 static int run_argc_allocated;
46 
47 void
48 run_setup (const char *prog)
49 {
50     char *cp;
51     int i;
52 
53     char *run_prog;
54 
55     /* clean out any malloc'ed values from run_argv */
56     for (i = 0; i < run_argc; i++)
57     {
58 	if (run_argv[i])
59 	{
60 	    free (run_argv[i]);
61 	    run_argv[i] = (char *) 0;
62 	}
63     }
64     run_argc = 0;
65 
66     run_prog = xstrdup (prog);
67 
68     /* put each word into run_argv, allocating it as we go */
69     for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
70 	run_add_arg (cp);
71 
72     free (run_prog);
73 }
74 
75 void
76 run_arg (s)
77     const char *s;
78 {
79     run_add_arg (s);
80 }
81 
82 /* Return a malloc'd copy of s, with double quotes around it.  */
83 static char *
84 quote (const char *s)
85 {
86     size_t s_len = 0;
87     char *copy = NULL;
88     char *scan = (char *) s;
89 
90     /* scan string for extra quotes ... */
91     while (*scan)
92 	if ('"' == *scan++)
93 	    s_len += 2;   /* one extra for the quote character */
94 	else
95 	    s_len++;
96     /* allocate length + byte for ending zero + for double quotes around */
97     scan = copy = xmalloc(s_len + 3);
98     *scan++ = '"';
99     while (*s)
100     {
101 	if ('"' == *s)
102 	    *scan++ = '\\';
103 	*scan++ = *s++;
104     }
105     /* ending quote and closing zero */
106     *scan++ = '"';
107     *scan++ = '\0';
108     return copy;
109 }
110 
111 static void
112 run_add_arg (s)
113     const char *s;
114 {
115     /* allocate more argv entries if we've run out */
116     if (run_argc >= run_argc_allocated)
117     {
118 	run_argc_allocated += 50;
119 	run_argv = (char **) xrealloc ((char *) run_argv,
120 				     run_argc_allocated * sizeof (char **));
121     }
122 
123     if (s)
124     {
125 	run_argv[run_argc] = (run_argc ? quote (s) : xstrdup (s));
126 	run_argc++;
127     }
128     else
129 	run_argv[run_argc] = (char *) 0;	/* not post-incremented on purpose! */
130 }
131 
132 int
133 run_exec (stin, stout, sterr, flags)
134     const char *stin;
135     const char *stout;
136     const char *sterr;
137     int flags;
138 {
139     int shin, shout, sherr;
140     int sain, saout, saerr;	/* saved handles */
141     int mode_out, mode_err;
142     int status = -1;
143     int rerrno = 0;
144     int rval   = -1;
145     void (*old_sigint) (int);
146 
147     if (trace)			/* if in trace mode */
148     {
149 	(void) fprintf (stderr, "-> system(");
150 	run_print (stderr);
151 	(void) fprintf (stderr, ")\n");
152     }
153 
154     /* Flush standard output and standard error, or otherwise we end
155        up with strange interleavings of stuff called from CYGWIN
156        vs. CMD.  */
157 
158     fflush (stderr);
159     fflush (stdout);
160 
161     if (noexec && (flags & RUN_REALLY) == 0) /* if in noexec mode */
162 	return (0);
163 
164     /*
165      * start the engine and take off
166      */
167 
168     /* make sure that we are null terminated, since we didn't calloc */
169     run_add_arg ((char *) 0);
170 
171     /* setup default file descriptor numbers */
172     shin = 0;
173     shout = 1;
174     sherr = 2;
175 
176     /* set the file modes for stdout and stderr */
177     mode_out = mode_err = O_WRONLY | O_CREAT;
178     mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC);
179     mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
180 
181     /* open the files as required, shXX are shadows of stdin... */
182     if (stin && (shin = open (stin, O_RDONLY)) == -1)
183     {
184 	rerrno = errno;
185 	error (0, errno, "cannot open %s for reading (prog %s)",
186 	       stin, run_argv[0]);
187 	goto out0;
188     }
189     if (stout && (shout = open (stout, mode_out, 0666)) == -1)
190     {
191 	rerrno = errno;
192 	error (0, errno, "cannot open %s for writing (prog %s)",
193 	       stout, run_argv[0]);
194 	goto out1;
195     }
196     if (sterr && (flags & RUN_COMBINED) == 0)
197     {
198 	if ((sherr = open (sterr, mode_err, 0666)) == -1)
199 	{
200 	    rerrno = errno;
201 	    error (0, errno, "cannot open %s for writing (prog %s)",
202 		   sterr, run_argv[0]);
203 	    goto out2;
204 	}
205     }
206     /* now save the standard handles */
207     sain = saout = saerr = -1;
208     sain  = dup( 0); /* dup stdin  */
209     saout = dup( 1); /* dup stdout */
210     saerr = dup( 2); /* dup stderr */
211 
212     /* the new handles will be dup'd to the standard handles
213      * for the spawn.
214      */
215 
216     if (shin != 0)
217       {
218 	(void) dup2 (shin, 0);
219 	(void) close (shin);
220       }
221     if (shout != 1)
222       {
223 	(void) dup2 (shout, 1);
224 	(void) close (shout);
225       }
226     if (flags & RUN_COMBINED)
227       (void) dup2 (1, 2);
228     else if (sherr != 2)
229       {
230 	(void) dup2 (sherr, 2);
231 	(void) close (sherr);
232       }
233 
234     /* Ignore signals while we're running this.  */
235     old_sigint = signal (SIGINT, SIG_IGN);
236 
237     /* dup'ing is done.  try to run it now */
238     rval = spawnvp ( P_WAIT, run_argv[0], run_argv);
239 
240     /* Restore signal handling.  */
241     signal (SIGINT, old_sigint);
242 
243     /* restore the original file handles   */
244     if (sain  != -1) {
245       (void) dup2( sain, 0);	/* re-connect stdin  */
246       (void) close( sain);
247     }
248     if (saout != -1) {
249       (void) dup2( saout, 1);	/* re-connect stdout */
250       (void) close( saout);
251     }
252     if (saerr != -1) {
253       (void) dup2( saerr, 2);	/* re-connect stderr */
254       (void) close( saerr);
255     }
256 
257     /* Flush standard output and standard error, or otherwise we end
258        up with strange interleavings of stuff called from CYGWIN
259        vs. CMD.  */
260 
261     fflush (stderr);
262     fflush (stdout);
263 
264     /* Recognize the return code for an interrupted subprocess.  */
265     if (rval == CONTROL_C_EXIT)
266         return 2;
267     else
268         return rval;		/* end, if all went coorect */
269 
270     /* error cases */
271     /* cleanup the open file descriptors */
272   out2:
273     if (stout)
274 	(void) close (shout);
275   out1:
276     if (stin)
277 	(void) close (shin);
278 
279   out0:
280     if (rerrno)
281 	errno = rerrno;
282     return (status);
283 }
284 
285 void
286 run_print (fp)
287     FILE *fp;
288 {
289     int i;
290 
291     for (i = 0; i < run_argc; i++)
292     {
293 	(void) fprintf (fp, "'%s'", run_argv[i]);
294 	if (i != run_argc - 1)
295 	    (void) fprintf (fp, " ");
296     }
297 }
298 
299 static char *
300 requote (const char *cmd)
301 {
302     char *requoted = xmalloc (strlen (cmd) + 1);
303     char *p = requoted;
304 
305     strcpy (requoted, cmd);
306     while ((p = strchr (p, '\'')) != NULL)
307     {
308         *p++ = '"';
309     }
310 
311     return requoted;
312 }
313 
314 FILE *
315 run_popen (cmd, mode)
316     const char *cmd;
317     const char *mode;
318 {
319     if (trace)
320 #ifdef SERVER_SUPPORT
321 	(void) fprintf (stderr, "%c-> run_popen(%s,%s)\n",
322 			(server_active) ? 'S' : ' ', cmd, mode);
323 #else
324 	(void) fprintf (stderr, "-> run_popen(%s,%s)\n", cmd, mode);
325 #endif
326     if (noexec)
327 	return (NULL);
328 
329     /* If the command string uses single quotes, turn them into
330        double quotes.  */
331     {
332         char *requoted = requote (cmd);
333 	/* Save and restore our file descriptors to work around
334 	   apparent bugs in _popen.  We are perhaps better off using
335 	   the win32 functions instead of _popen.  */
336 	int old_stdin = dup (STDIN_FILENO);
337 	int old_stdout = dup (STDOUT_FILENO);
338 	int old_stderr = dup (STDERR_FILENO);
339 
340 	FILE *result = popen (requoted, mode);
341 
342 	dup2 (old_stdin, STDIN_FILENO);
343 	dup2 (old_stdout, STDOUT_FILENO);
344 	dup2 (old_stderr, STDERR_FILENO);
345 	close (old_stdin);
346 	close (old_stdout);
347 	close (old_stderr);
348 
349 	free (requoted);
350 	return result;
351     }
352 }
353 
354 
355 /* Running children with pipes connected to them.  */
356 
357 /* It's kind of ridiculous the hoops we're jumping through to get
358    this working.  _pipe and dup2 and _spawnmumble work just fine, except
359    that the child inherits a file descriptor for the writing end of the
360    pipe, and thus will never receive end-of-file on it.  If you know of
361    a better way to implement the piped_child function, please let me know.
362 
363    You can apparently specify _O_NOINHERIT when you open a file, but there's
364    apparently no fcntl function, so you can't change that bit on an existing
365    file descriptor.  */
366 
367 /* Given a handle, make an inheritable duplicate of it, and close
368    the original.  */
369 static HANDLE
370 inheritable (HANDLE in)
371 {
372     HANDLE copy;
373     HANDLE self = GetCurrentProcess ();
374 
375     if (! DuplicateHandle (self, in, self, &copy,
376 			   0, 1 /* fInherit */,
377 			   DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
378         return INVALID_HANDLE_VALUE;
379 
380     return copy;
381 }
382 
383 
384 /* Initialize the SECURITY_ATTRIBUTES structure *LPSA.  Set its
385    bInheritHandle flag according to INHERIT.  */
386 static void
387 init_sa (LPSECURITY_ATTRIBUTES lpsa, BOOL inherit)
388 {
389   lpsa->nLength = sizeof(*lpsa);
390   lpsa->bInheritHandle = inherit;
391   lpsa->lpSecurityDescriptor = NULL;
392 }
393 
394 
395 enum inherit_pipe { inherit_reading, inherit_writing };
396 
397 /* Create a pipe.  Set READWRITE[0] to its reading end, and
398    READWRITE[1] to its writing end.  If END is inherit_reading,
399    make the only the handle for the pipe's reading end inheritable.
400    If END is inherit_writing, make only the handle for the pipe's
401    writing end inheritable.  Return 0 if we succeed, -1 if we fail.
402 
403    Why does inheritability matter?  Consider the case of a
404    pipe carrying data from the parent process to the child
405    process.  The child wants to read data from the parent until
406    it reaches the EOF.  Now, the only way to send an EOF on a pipe
407    is to close all the handles to its writing end.  Obviously, the
408    parent has a handle to the writing end when it creates the child.
409    If the child inherits this handle, then it will never close it
410    (the child has no idea it's inherited it), and will thus never
411    receive an EOF on the pipe because it's holding a handle
412    to it.
413 
414    In Unix, the child process closes the pipe ends before it execs.
415    In Windows NT, you create the pipe with uninheritable handles, and then use
416    DuplicateHandle to make the appropriate ends inheritable.  */
417 
418 static int
419 my_pipe (HANDLE *readwrite, enum inherit_pipe end)
420 {
421     HANDLE read, write;
422     SECURITY_ATTRIBUTES sa;
423 
424     init_sa (&sa, 0);
425     if (! CreatePipe (&read, &write, &sa, 1 << 13))
426     {
427         errno = EMFILE;
428         return -1;
429     }
430     if (end == inherit_reading)
431         read = inheritable (read);
432     else
433         write = inheritable (write);
434 
435     if (read == INVALID_HANDLE_VALUE
436         || write == INVALID_HANDLE_VALUE)
437     {
438         CloseHandle (read);
439 	CloseHandle (write);
440 	errno = EMFILE;
441 	return -1;
442     }
443 
444     readwrite[0] = read;
445     readwrite[1] = write;
446 
447     return 0;
448 }
449 
450 
451 /* Initialize the STARTUPINFO structure *LPSI.  */
452 static void
453 init_si (LPSTARTUPINFO lpsi)
454 {
455   memset (lpsi, 0, sizeof (*lpsi));
456   lpsi->cb = sizeof(*lpsi);
457   lpsi->lpReserved = NULL;
458   lpsi->lpTitle = NULL;
459   lpsi->lpReserved2 = NULL;
460   lpsi->cbReserved2 = 0;
461   lpsi->lpDesktop = NULL;
462   lpsi->dwFlags = 0;
463 }
464 
465 
466 /* Create a child process running COMMAND with IN as its standard input,
467    and OUT as its standard output.  Return a handle to the child, or
468    INVALID_HANDLE_VALUE.  */
469 static int
470 start_child (char *command, HANDLE in, HANDLE out)
471 {
472   STARTUPINFO si;
473   PROCESS_INFORMATION pi;
474   BOOL status;
475 
476   /* The STARTUPINFO structure can specify handles to pass to the
477      child as its standard input, output, and error.  */
478   init_si (&si);
479   si.hStdInput = in;
480   si.hStdOutput = out;
481   si.hStdError  = (HANDLE) _get_osfhandle (2);
482   si.dwFlags = STARTF_USESTDHANDLES;
483 
484   status = CreateProcess ((LPCTSTR) NULL,
485                           (LPTSTR) command,
486 		          (LPSECURITY_ATTRIBUTES) NULL, /* lpsaProcess */
487 		          (LPSECURITY_ATTRIBUTES) NULL, /* lpsaThread */
488 		          TRUE, /* fInheritHandles */
489 		          0,    /* fdwCreate */
490 		          (LPVOID) 0, /* lpvEnvironment */
491 		          (LPCTSTR) 0, /* lpszCurDir */
492 		          &si,  /* lpsiStartInfo */
493 		          &pi); /* lppiProcInfo */
494 
495   if (! status)
496   {
497       DWORD error_code = GetLastError ();
498       switch (error_code)
499       {
500       case ERROR_NOT_ENOUGH_MEMORY:
501       case ERROR_OUTOFMEMORY:
502           errno = ENOMEM; break;
503       case ERROR_BAD_EXE_FORMAT:
504           errno = ENOEXEC; break;
505       case ERROR_ACCESS_DENIED:
506           errno = EACCES; break;
507       case ERROR_NOT_READY:
508       case ERROR_FILE_NOT_FOUND:
509       case ERROR_PATH_NOT_FOUND:
510       default:
511           errno = ENOENT; break;
512       }
513       return (int) INVALID_HANDLE_VALUE;
514   }
515 
516   /* The _spawn and _cwait functions in the C runtime library
517      seem to operate on raw NT handles, not PID's.  Odd, but we'll
518      deal.  */
519   return (int) pi.hProcess;
520 }
521 
522 
523 /* Given an array of arguments that one might pass to spawnv,
524    construct a command line that one might pass to CreateProcess.
525    Try to quote things appropriately.  */
526 static char *
527 build_command (char **argv)
528 {
529     int len;
530 
531     /* Compute the total length the command will have.  */
532     {
533         int i;
534 
535 	len = 0;
536         for (i = 0; argv[i]; i++)
537 	{
538 	    char *p;
539 
540 	    len += 2;  /* for the double quotes */
541 
542 	    for (p = argv[i]; *p; p++)
543 	    {
544 	        if (*p == '"')
545 		    len += 2;
546 		else
547 		    len++;
548 	    }
549 	    len++;  /* for the space or the '\0'  */
550 	}
551     }
552 
553     {
554 	/* The + 10 is in case len is 0.  */
555         char *command = (char *) malloc (len + 10);
556 	int i;
557 	char *p;
558 
559 	if (! command)
560 	{
561 	    errno = ENOMEM;
562 	    return command;
563 	}
564 
565 	p = command;
566         *p = '\0';
567 	/* copy each element of argv to command, putting each command
568 	   in double quotes, and backslashing any quotes that appear
569 	   within an argument.  */
570 	for (i = 0; argv[i]; i++)
571 	{
572 	    char *a;
573 	    *p++ = '"';
574 	    for (a = argv[i]; *a; a++)
575 	    {
576 	        if (*a == '"')
577 		    *p++ = '\\', *p++ = '"';
578 		else
579 		    *p++ = *a;
580 	    }
581 	    *p++ = '"';
582 	    *p++ = ' ';
583 	}
584 	if (p > command)
585 	    p[-1] = '\0';
586 
587         return command;
588     }
589 }
590 
591 
592 /* Create an asynchronous child process executing ARGV,
593    with its standard input and output connected to the
594    parent with pipes.  Set *TO to the file descriptor on
595    which one writes data for the child; set *FROM to
596    the file descriptor from which one reads data from the child.
597    Return the handle of the child process (this is what
598    _cwait and waitpid expect).  */
599 int
600 piped_child (char **argv, int *to, int *from)
601 {
602   int child;
603   HANDLE pipein[2], pipeout[2];
604   char *command;
605 
606   /* Turn argv into a form acceptable to CreateProcess.  */
607   command = build_command (argv);
608   if (! command)
609       return -1;
610 
611   /* Create pipes for communicating with child.  Arrange for
612      the child not to inherit the ends it won't use.  */
613   if (my_pipe (pipein, inherit_reading) == -1
614       || my_pipe (pipeout, inherit_writing) == -1)
615       return -1;
616 
617   child = start_child (command, pipein[0], pipeout[1]);
618   free (command);
619   if (child == (int) INVALID_HANDLE_VALUE)
620       return -1;
621 
622   /* Close the pipe ends the parent doesn't use.  */
623   CloseHandle (pipein[0]);
624   CloseHandle (pipeout[1]);
625 
626   /* Given the pipe handles, turn them into file descriptors for
627      use by the caller.  */
628   if ((*to      = _open_osfhandle ((long) pipein[1],  _O_BINARY)) == -1
629       || (*from = _open_osfhandle ((long) pipeout[0], _O_BINARY)) == -1)
630       return -1;
631 
632   return child;
633 }
634 
635 /*
636  * dir = 0 : main proc writes to new proc, which writes to oldfd
637  * dir = 1 : main proc reads from new proc, which reads from oldfd
638  *
639  * Returns: a file descriptor.  On failure (e.g., the exec fails),
640  * then filter_stream_through_program() complains and dies.
641  */
642 
643 int
644 filter_stream_through_program (oldfd, dir, prog, pidp)
645      int oldfd, dir;
646      char **prog;
647      pid_t *pidp;
648 {
649     HANDLE pipe[2];
650     char *command;
651     int child;
652     HANDLE oldfd_handle;
653     HANDLE newfd_handle;
654     int newfd;
655 
656     /* Get the OS handle associated with oldfd, to be passed to the child.  */
657     if ((oldfd_handle = (HANDLE) _get_osfhandle (oldfd)) < 0)
658 	error (1, errno, "cannot _get_osfhandle");
659 
660     if (dir)
661     {
662         /* insert child before parent, pipe goes child->parent.  */
663 	if (my_pipe (pipe, inherit_writing) == -1)
664 	    error (1, errno, "cannot my_pipe");
665 	if ((command = build_command (prog)) == NULL)
666 	    error (1, errno, "cannot build_command");
667 	child = start_child (command, oldfd_handle, pipe[1]);
668 	free (command);
669 	if (child == (int) INVALID_HANDLE_VALUE)
670 	    error (1, errno, "cannot start_child");
671 	close (oldfd);
672 	CloseHandle (pipe[1]);
673 	newfd_handle = pipe[0];
674     }
675     else
676     {
677         /* insert child after parent, pipe goes parent->child.  */
678 	if (my_pipe (pipe, inherit_reading) == -1)
679 	    error (1, errno, "cannot my_pipe");
680 	if ((command = build_command (prog)) == NULL)
681 	    error (1, errno, "cannot build_command");
682 	child = start_child (command, pipe[0], oldfd_handle);
683 	free (command);
684 	if (child == (int) INVALID_HANDLE_VALUE)
685 	    error (1, errno, "cannot start_child");
686 	close (oldfd);
687 	CloseHandle (pipe[0]);
688 	newfd_handle = pipe[1];
689     }
690 
691     if ((newfd = _open_osfhandle ((long) newfd_handle, _O_BINARY)) == -1)
692         error (1, errno, "cannot _open_osfhandle");
693 
694     if (pidp)
695 	*pidp = child;
696     return newfd;
697 }
698 
699 
700 /* Arrange for the file descriptor FD to not be inherited by child
701    processes.  At the moment, CVS uses this function only on pipes
702    returned by piped_child, and our implementation of piped_child
703    takes care of setting the file handles' inheritability, so this
704    can be a no-op.  */
705 void
706 close_on_exec (int fd)
707 {
708 }
709