Update copyright notices.
[libreoffice:gnu-make-lo.git] / w32 / subproc / sub_proc.c
1 /* Process handling for Windows.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4 This file is part of GNU Make.
5
6 GNU Make is free software; you can redistribute it and/or modify it under the
7 terms of the GNU General Public License as published by the Free Software
8 Foundation; either version 3 of the License, or (at your option) any later
9 version.
10
11 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #ifdef _MSC_VER
22 # include <stddef.h>    /* for intptr_t */
23 #else
24 # include <stdint.h>
25 #endif
26 #include <process.h>  /* for msvc _beginthreadex, _endthreadex */
27 #include <signal.h>
28 #include <windows.h>
29
30 #include "sub_proc.h"
31 #include "proc.h"
32 #include "w32err.h"
33 #include "debug.h"
34
35 static char *make_command_line(char *shell_name, char *exec_path, char **argv);
36 extern char *xmalloc (unsigned int);
37
38 typedef struct sub_process_t {
39         intptr_t sv_stdin[2];
40         intptr_t sv_stdout[2];
41         intptr_t sv_stderr[2];
42         int using_pipes;
43         char *inp;
44         DWORD incnt;
45         char * volatile outp;
46         volatile DWORD outcnt;
47         char * volatile errp;
48         volatile DWORD errcnt;
49         pid_t pid;
50         int exit_code;
51         int signal;
52         long last_err;
53         long lerrno;
54 } sub_process;
55
56 /* keep track of children so we can implement a waitpid-like routine */
57 static sub_process *proc_array[MAXIMUM_WAIT_OBJECTS];
58 static int proc_index = 0;
59 static int fake_exits_pending = 0;
60
61 /* Windows jobserver implementation variables */
62 static char jobserver_semaphore_name[MAX_PATH + 1];
63 static HANDLE jobserver_semaphore = NULL;
64
65 /* Open existing jobserver semaphore */
66 int open_jobserver_semaphore(const char* name)
67 {
68     jobserver_semaphore = OpenSemaphore(
69         SEMAPHORE_ALL_ACCESS,   // Semaphore access setting
70         FALSE,                  // Child processes DON'T inherit
71         name);                  // Semaphore name
72
73     if (jobserver_semaphore == NULL)
74         return 0;
75
76     return 1;        
77 }
78
79 /* Create new jobserver semaphore */
80 int create_jobserver_semaphore(int tokens)
81 {
82     sprintf(jobserver_semaphore_name, "gmake_semaphore_%d", _getpid());
83
84     jobserver_semaphore = CreateSemaphore(
85         NULL,                           // Use default security descriptor
86         tokens,                         // Initial count
87         tokens,                         // Maximum count
88         jobserver_semaphore_name);      // Semaphore name
89
90     if (jobserver_semaphore == NULL)
91         return 0;
92
93     return 1;        
94 }
95
96 /* Close jobserver semaphore */
97 void free_jobserver_semaphore()
98 {
99     if (jobserver_semaphore != NULL)
100     {
101         CloseHandle(jobserver_semaphore);
102         jobserver_semaphore = NULL;
103     }
104 }
105
106 /* Decrement semaphore count */
107 int acquire_jobserver_semaphore()
108 {
109     DWORD dwEvent = WaitForSingleObject(
110         jobserver_semaphore,    // Handle to semaphore
111         0);                     // DON'T wait on semaphore
112
113     return (dwEvent == WAIT_OBJECT_0);
114 }
115
116 /* Increment semaphore count */
117 int release_jobserver_semaphore()
118 {
119     BOOL bResult = ReleaseSemaphore( 
120         jobserver_semaphore,    // handle to semaphore
121         1,                      // increase count by one
122         NULL);                  // not interested in previous count
123
124     return (bResult);
125 }
126
127 int has_jobserver_semaphore()
128 {
129     return (jobserver_semaphore != NULL);
130 }
131
132 char* get_jobserver_semaphore_name()
133 {
134     return (jobserver_semaphore_name);
135 }
136
137 /* Wait for either the jobserver semaphore to become signalled or one of our
138  * child processes to terminate.
139  */
140 int wait_for_semaphore_or_child_process()
141 {
142     HANDLE handles[MAXIMUM_WAIT_OBJECTS];
143     DWORD dwHandleCount = 1;
144     DWORD dwEvent;
145     int i;
146
147     /* Add jobserver semaphore to first slot. */
148     handles[0] = jobserver_semaphore;
149
150     /* Build array of handles to wait for */
151     for (i = 0; i < proc_index; i++) 
152     {
153         /* Don't wait on child processes that have already finished */
154         if (fake_exits_pending && proc_array[i]->exit_code)
155             continue;
156
157         handles[dwHandleCount++] = (HANDLE) proc_array[i]->pid;
158     }
159
160     dwEvent = WaitForMultipleObjects( 
161         dwHandleCount,  // number of objects in array
162         handles,        // array of objects
163         FALSE,          // wait for any object
164         INFINITE);      // wait until object is signalled
165
166     switch(dwEvent)
167     {
168       case WAIT_FAILED:
169         return -1;
170
171       case WAIT_OBJECT_0:
172         /* Indicate that the semaphore was signalled */
173         return 1;
174
175       default:
176         /* Assume that one or more of the child processes terminated. */
177         return 0;
178     }
179 }
180
181 /*
182  * When a process has been waited for, adjust the wait state
183  * array so that we don't wait for it again
184  */
185 static void
186 process_adjust_wait_state(sub_process* pproc)
187 {
188         int i;
189
190         if (!proc_index)
191                 return;
192
193         for (i = 0; i < proc_index; i++)
194                 if (proc_array[i]->pid == pproc->pid)
195                         break;
196
197         if (i < proc_index) {
198                 proc_index--;
199                 if (i != proc_index)
200                         memmove(&proc_array[i], &proc_array[i+1],
201                                 (proc_index-i) * sizeof(sub_process*));
202                 proc_array[proc_index] = NULL;
203         }
204 }
205
206 /*
207  * Waits for any of the registered child processes to finish.
208  */
209 static sub_process *
210 process_wait_for_any_private(int block, DWORD* pdwWaitStatus)
211 {
212         HANDLE handles[MAXIMUM_WAIT_OBJECTS];
213         DWORD retval, which;
214         int i;
215
216         if (!proc_index)
217                 return NULL;
218
219         /* build array of handles to wait for */
220         for (i = 0; i < proc_index; i++) {
221                 handles[i] = (HANDLE) proc_array[i]->pid;
222
223                 if (fake_exits_pending && proc_array[i]->exit_code)
224                         break;
225         }
226
227         /* wait for someone to exit */
228         if (!fake_exits_pending) {
229                 retval = WaitForMultipleObjects(proc_index, handles, FALSE, (block ? INFINITE : 0));
230                 which = retval - WAIT_OBJECT_0;
231         } else {
232                 fake_exits_pending--;
233                 retval = !WAIT_FAILED;
234                 which = i;
235         }
236
237         /* If the pointer is not NULL, set the wait status result variable. */
238         if (pdwWaitStatus)
239             *pdwWaitStatus = retval;
240
241         /* return pointer to process */
242         if ((retval == WAIT_TIMEOUT) || (retval == WAIT_FAILED)) {
243                 return NULL;
244         }
245         else {
246                 sub_process* pproc = proc_array[which];
247                 process_adjust_wait_state(pproc);
248                 return pproc;
249         } 
250 }
251
252 /*
253  * Terminate a process.
254  */
255 BOOL
256 process_kill(HANDLE proc, int signal)
257 {
258         sub_process* pproc = (sub_process*) proc;
259         pproc->signal = signal;
260         return (TerminateProcess((HANDLE) pproc->pid, signal));
261 }
262
263 /*
264  * Use this function to register processes you wish to wait for by
265  * calling process_file_io(NULL) or process_wait_any(). This must be done
266  * because it is possible for callers of this library to reuse the same
267  * handle for multiple processes launches :-(
268  */
269 void
270 process_register(HANDLE proc)
271 {
272         if (proc_index < MAXIMUM_WAIT_OBJECTS)
273                 proc_array[proc_index++] = (sub_process *) proc;
274 }
275
276 /*
277  * Return the number of processes that we are still waiting for.
278  */
279 int
280 process_used_slots(void)
281 {
282         return proc_index;
283 }
284
285 /*
286  * Public function which works kind of like waitpid(). Wait for any
287  * of the children to die and return results. To call this function,
288  * you must do 1 of things:
289  *
290  *      x = process_easy(...);
291  *
292  * or
293  *
294  *      x = process_init_fd();
295  *      process_register(x);
296  *
297  * or
298  *
299  *      x = process_init();
300  *      process_register(x);
301  *
302  * You must NOT then call process_pipe_io() because this function is
303  * not capable of handling automatic notification of any child
304  * death.
305  */
306
307 HANDLE
308 process_wait_for_any(int block, DWORD* pdwWaitStatus)
309 {
310         sub_process* pproc = process_wait_for_any_private(block, pdwWaitStatus);
311
312         if (!pproc)
313                 return NULL;
314         else {
315                 /*
316                  * Ouch! can't tell caller if this fails directly. Caller
317                  * will have to use process_last_err()
318                  */
319                 (void) process_file_io(pproc);
320                 return ((HANDLE) pproc);
321         }
322 }
323
324 long
325 process_signal(HANDLE proc)
326 {
327         if (proc == INVALID_HANDLE_VALUE) return 0;
328         return (((sub_process *)proc)->signal);
329 }
330
331 long
332 process_last_err(HANDLE proc)
333 {
334         if (proc == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
335         return (((sub_process *)proc)->last_err);
336 }
337
338 long
339 process_exit_code(HANDLE proc)
340 {
341         if (proc == INVALID_HANDLE_VALUE) return EXIT_FAILURE;
342         return (((sub_process *)proc)->exit_code);
343 }
344
345 /*
346 2006-02:
347 All the following functions are currently unused.
348 All of them would crash gmake if called with argument INVALID_HANDLE_VALUE.
349 Hence whoever wants to use one of this functions must invent and implement
350 a reasonable error handling for this function.
351
352 char *
353 process_outbuf(HANDLE proc)
354 {
355         return (((sub_process *)proc)->outp);
356 }
357
358 char *
359 process_errbuf(HANDLE proc)
360 {
361         return (((sub_process *)proc)->errp);
362 }
363
364 int
365 process_outcnt(HANDLE proc)
366 {
367         return (((sub_process *)proc)->outcnt);
368 }
369
370 int
371 process_errcnt(HANDLE proc)
372 {
373         return (((sub_process *)proc)->errcnt);
374 }
375
376 void
377 process_pipes(HANDLE proc, int pipes[3])
378 {
379         pipes[0] = ((sub_process *)proc)->sv_stdin[0];
380         pipes[1] = ((sub_process *)proc)->sv_stdout[0];
381         pipes[2] = ((sub_process *)proc)->sv_stderr[0];
382         return;
383 }
384 */
385
386         HANDLE
387 process_init()
388 {
389         sub_process *pproc;
390         /*
391          * open file descriptors for attaching stdin/stdout/sterr
392          */
393         HANDLE stdin_pipes[2];
394         HANDLE stdout_pipes[2];
395         HANDLE stderr_pipes[2];
396         SECURITY_ATTRIBUTES inherit;
397         BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
398
399         pproc = malloc(sizeof(*pproc));
400         memset(pproc, 0, sizeof(*pproc));
401
402         /* We can't use NULL for lpSecurityDescriptor because that
403            uses the default security descriptor of the calling process.
404            Instead we use a security descriptor with no DACL.  This
405            allows nonrestricted access to the associated objects. */
406
407         if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd),
408                                           SECURITY_DESCRIPTOR_REVISION)) {
409                 pproc->last_err = GetLastError();
410                 pproc->lerrno = E_SCALL;
411                 return((HANDLE)pproc);
412         }
413
414         inherit.nLength = sizeof(inherit);
415         inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd);
416         inherit.bInheritHandle = TRUE;
417
418         // By convention, parent gets pipe[0], and child gets pipe[1]
419         // This means the READ side of stdin pipe goes into pipe[1]
420         // and the WRITE side of the stdout and stderr pipes go into pipe[1]
421         if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE ||
422         CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE ||
423         CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) {
424
425                 pproc->last_err = GetLastError();
426                 pproc->lerrno = E_SCALL;
427                 return((HANDLE)pproc);
428         }
429
430         //
431         // Mark the parent sides of the pipes as non-inheritable
432         //
433         if (SetHandleInformation(stdin_pipes[0],
434                                 HANDLE_FLAG_INHERIT, 0) == FALSE ||
435                 SetHandleInformation(stdout_pipes[0],
436                                 HANDLE_FLAG_INHERIT, 0) == FALSE ||
437                 SetHandleInformation(stderr_pipes[0],
438                                 HANDLE_FLAG_INHERIT, 0) == FALSE) {
439
440                 pproc->last_err = GetLastError();
441                 pproc->lerrno = E_SCALL;
442                 return((HANDLE)pproc);
443         }
444         pproc->sv_stdin[0]  = (intptr_t) stdin_pipes[0];
445         pproc->sv_stdin[1]  = (intptr_t) stdin_pipes[1];
446         pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0];
447         pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1];
448         pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0];
449         pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1];
450
451         pproc->using_pipes = 1;
452
453         pproc->lerrno = 0;
454
455         return((HANDLE)pproc);
456 }
457
458
459         HANDLE
460 process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
461 {
462         sub_process *pproc;
463
464         pproc = malloc(sizeof(*pproc));
465         memset(pproc, 0, sizeof(*pproc));
466
467         /*
468          * Just pass the provided file handles to the 'child side' of the
469          * pipe, bypassing pipes altogether.
470          */
471         pproc->sv_stdin[1]  = (intptr_t) stdinh;
472         pproc->sv_stdout[1] = (intptr_t) stdouth;
473         pproc->sv_stderr[1] = (intptr_t) stderrh;
474
475         pproc->last_err = pproc->lerrno = 0;
476
477         return((HANDLE)pproc);
478 }
479
480
481 static HANDLE
482 find_file(const char *exec_path, const char *path_var,
483           char *full_fname, DWORD full_len)
484 {
485         HANDLE exec_handle;
486         char *fname;
487         char *ext;
488         DWORD req_len;
489         int i;
490         static const char *extensions[] =
491           /* Should .com come before no-extension case?  */
492           { ".exe", ".cmd", ".bat", "", ".com", NULL };
493
494         fname = xmalloc(strlen(exec_path) + 5);
495         strcpy(fname, exec_path);
496         ext = fname + strlen(fname);
497
498         for (i = 0; extensions[i]; i++) {
499                 strcpy(ext, extensions[i]);
500                 if (((req_len = SearchPath (path_var, fname, NULL, full_len,
501                                             full_fname, NULL)) > 0
502                      /* For compatibility with previous code, which
503                         used OpenFile, and with Windows operation in
504                         general, also look in various default
505                         locations, such as Windows directory and
506                         Windows System directory.  Warning: this also
507                         searches PATH in the Make's environment, which
508                         might not be what the Makefile wants, but it
509                         seems to be OK as a fallback, after the
510                         previous SearchPath failed to find on child's
511                         PATH.  */
512                      || (req_len = SearchPath (NULL, fname, NULL, full_len,
513                                                full_fname, NULL)) > 0)
514                     && req_len <= full_len
515                     && (exec_handle =
516                                 CreateFile(full_fname,
517                                            GENERIC_READ,
518                                            FILE_SHARE_READ | FILE_SHARE_WRITE,
519                                            NULL,
520                                            OPEN_EXISTING,
521                                            FILE_ATTRIBUTE_NORMAL,
522                                            NULL)) != INVALID_HANDLE_VALUE) {
523                         free(fname);
524                         return(exec_handle);
525                 }
526         }
527
528         free(fname);
529         return INVALID_HANDLE_VALUE;
530 }
531
532
533 /*
534  * Description:   Create the child process to be helped
535  *
536  * Returns: success <=> 0
537  *
538  * Notes/Dependencies:
539  */
540 long
541 process_begin(
542         HANDLE proc,
543         char **argv,
544         char **envp,
545         char *exec_path,
546         char *as_user)
547 {
548         sub_process *pproc = (sub_process *)proc;
549         char *shell_name = 0;
550         int file_not_found=0;
551         HANDLE exec_handle;
552         char exec_fname[MAX_PATH];
553         const char *path_var = NULL;
554         char **ep;
555         char buf[256];
556         DWORD bytes_returned;
557         DWORD flags;
558         char *command_line;
559         STARTUPINFO startInfo;
560         PROCESS_INFORMATION procInfo;
561         char *envblk=NULL;
562
563         /*
564          *  Shell script detection...  if the exec_path starts with #! then
565          *  we want to exec shell-script-name exec-path, not just exec-path
566          *  NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl.  We do not
567          *  hard-code the path to the shell or perl or whatever:  Instead, we
568          *  assume it's in the path somewhere (generally, the NT tools
569          *  bin directory)
570          */
571
572         /* Use the Makefile's value of PATH to look for the program to
573            execute, because it could be different from Make's PATH
574            (e.g., if the target sets its own value.  */
575         if (envp)
576                 for (ep = envp; *ep; ep++) {
577                         if (strncmp (*ep, "PATH=", 5) == 0
578                             || strncmp (*ep, "Path=", 5) == 0) {
579                                 path_var = *ep + 5;
580                                 break;
581                         }
582                 }
583         exec_handle = find_file(exec_path, path_var,
584                                 exec_fname, sizeof(exec_fname));
585
586         /*
587          * If we couldn't open the file, just assume that Windows will be
588          * somehow able to find and execute it.
589          */
590         if (exec_handle == INVALID_HANDLE_VALUE) {
591                 file_not_found++;
592         }
593         else {
594                 /* Attempt to read the first line of the file */
595                 if (ReadFile( exec_handle,
596                                 buf, sizeof(buf) - 1, /* leave room for trailing NULL */
597                                 &bytes_returned, 0) == FALSE || bytes_returned < 2) {
598
599                         pproc->last_err = GetLastError();
600                         pproc->lerrno = E_IO;
601                         CloseHandle(exec_handle);
602                         return(-1);
603                 }
604                 if (buf[0] == '#' && buf[1] == '!') {
605                         /*
606                          *  This is a shell script...  Change the command line from
607                          *      exec_path args to shell_name exec_path args
608                          */
609                         char *p;
610
611                         /*  Make sure buf is NULL terminated */
612                         buf[bytes_returned] = 0;
613                         /*
614                          * Depending on the file system type, etc. the first line
615                          * of the shell script may end with newline or newline-carriage-return
616                          * Whatever it ends with, cut it off.
617                          */
618                         p= strchr(buf, '\n');
619                         if (p)
620                                 *p = 0;
621                         p = strchr(buf, '\r');
622                         if (p)
623                                 *p = 0;
624
625                         /*
626                          *  Find base name of shell
627                          */
628                         shell_name = strrchr( buf, '/');
629                         if (shell_name) {
630                                 shell_name++;
631                         } else {
632                                 shell_name = &buf[2];/* skipping "#!" */
633                         }
634
635                 }
636                 CloseHandle(exec_handle);
637         }
638
639         flags = 0;
640
641         if (file_not_found)
642                 command_line = make_command_line( shell_name, exec_path, argv);
643         else
644                 command_line = make_command_line( shell_name, exec_fname, argv);
645
646         if ( command_line == NULL ) {
647                 pproc->last_err = 0;
648                 pproc->lerrno = E_NO_MEM;
649                 return(-1);
650         }
651
652         if (envp) {
653                 if (arr2envblk(envp, &envblk) ==FALSE) {
654                         pproc->last_err = 0;
655                         pproc->lerrno = E_NO_MEM;
656                         free( command_line );
657                         return(-1);
658                 }
659         }
660
661         if ((shell_name) || (file_not_found)) {
662                 exec_path = 0;  /* Search for the program in %Path% */
663         } else {
664                 exec_path = exec_fname;
665         }
666
667         /*
668          *  Set up inherited stdin, stdout, stderr for child
669          */
670         GetStartupInfo(&startInfo);
671         startInfo.dwFlags = STARTF_USESTDHANDLES;
672         startInfo.lpReserved = 0;
673         startInfo.cbReserved2 = 0;
674         startInfo.lpReserved2 = 0;
675         startInfo.lpTitle = shell_name ? shell_name : exec_path;
676         startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
677         startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
678         startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];
679
680         if (as_user) {
681                 if (envblk) free(envblk);
682                 return -1;
683         } else {
684                 DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n",
685                         exec_path ? exec_path : "NULL",
686                         command_line ? command_line : "NULL"));
687                 if (CreateProcess(
688                         exec_path,
689                         command_line,
690                         NULL,
691                         0, /* default security attributes for thread */
692                         TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
693                         flags,
694                         envblk,
695                         0, /* default starting directory */
696                         &startInfo,
697                         &procInfo) == FALSE) {
698
699                         pproc->last_err = GetLastError();
700                         pproc->lerrno = E_FORK;
701                         fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
702                                 exec_path ? exec_path : "NULL", command_line);
703                         if (envblk) free(envblk);
704                         free( command_line );
705                         return(-1);
706                 }
707         }
708
709         pproc->pid = (pid_t)procInfo.hProcess;
710         /* Close the thread handle -- we'll just watch the process */
711         CloseHandle(procInfo.hThread);
712
713         /* Close the halves of the pipes we don't need */
714         CloseHandle((HANDLE)pproc->sv_stdin[1]);
715         CloseHandle((HANDLE)pproc->sv_stdout[1]);
716         CloseHandle((HANDLE)pproc->sv_stderr[1]);
717         pproc->sv_stdin[1] = 0;
718         pproc->sv_stdout[1] = 0;
719         pproc->sv_stderr[1] = 0;
720
721         free( command_line );
722         if (envblk) free(envblk);
723         pproc->lerrno=0;
724         return 0;
725 }
726
727
728
729 static DWORD
730 proc_stdin_thread(sub_process *pproc)
731 {
732         DWORD in_done;
733         for (;;) {
734                 if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt,
735                                          &in_done, NULL) == FALSE)
736                         _endthreadex(0);
737                 // This if should never be true for anonymous pipes, but gives
738                 // us a chance to change I/O mechanisms later
739                 if (in_done < pproc->incnt) {
740                         pproc->incnt -= in_done;
741                         pproc->inp += in_done;
742                 } else {
743                         _endthreadex(0);
744                 }
745         }
746         return 0; // for compiler warnings only.. not reached
747 }
748
749 static DWORD
750 proc_stdout_thread(sub_process *pproc)
751 {
752         DWORD bufsize = 1024;
753         char c;
754         DWORD nread;
755         pproc->outp = malloc(bufsize);
756         if (pproc->outp == NULL)
757                 _endthreadex(0);
758         pproc->outcnt = 0;
759
760         for (;;) {
761                 if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL)
762                                         == FALSE) {
763 /*                      map_windows32_error_to_string(GetLastError());*/
764                         _endthreadex(0);
765                 }
766                 if (nread == 0)
767                         _endthreadex(0);
768                 if (pproc->outcnt + nread > bufsize) {
769                         bufsize += nread + 512;
770                         pproc->outp = realloc(pproc->outp, bufsize);
771                         if (pproc->outp == NULL) {
772                                 pproc->outcnt = 0;
773                                 _endthreadex(0);
774                         }
775                 }
776                 pproc->outp[pproc->outcnt++] = c;
777         }
778         return 0;
779 }
780
781 static DWORD
782 proc_stderr_thread(sub_process *pproc)
783 {
784         DWORD bufsize = 1024;
785         char c;
786         DWORD nread;
787         pproc->errp = malloc(bufsize);
788         if (pproc->errp == NULL)
789                 _endthreadex(0);
790         pproc->errcnt = 0;
791
792         for (;;) {
793                 if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) {
794                         map_windows32_error_to_string(GetLastError());
795                         _endthreadex(0);
796                 }
797                 if (nread == 0)
798                         _endthreadex(0);
799                 if (pproc->errcnt + nread > bufsize) {
800                         bufsize += nread + 512;
801                         pproc->errp = realloc(pproc->errp, bufsize);
802                         if (pproc->errp == NULL) {
803                                 pproc->errcnt = 0;
804                                 _endthreadex(0);
805                         }
806                 }
807                 pproc->errp[pproc->errcnt++] = c;
808         }
809         return 0;
810 }
811
812
813 /*
814  * Purpose: collects output from child process and returns results
815  *
816  * Description:
817  *
818  * Returns:
819  *
820  * Notes/Dependencies:
821  */
822         long
823 process_pipe_io(
824         HANDLE proc,
825         char *stdin_data,
826         int stdin_data_len)
827 {
828         sub_process *pproc = (sub_process *)proc;
829         bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE;
830         HANDLE childhand = (HANDLE) pproc->pid;
831         HANDLE tStdin = NULL, tStdout = NULL, tStderr = NULL;
832         unsigned int dwStdin, dwStdout, dwStderr;
833         HANDLE wait_list[4];
834         DWORD wait_count;
835         DWORD wait_return;
836         HANDLE ready_hand;
837         bool_t child_dead = FALSE;
838         BOOL GetExitCodeResult;
839
840         /*
841          *  Create stdin thread, if needed
842          */
843         pproc->inp = stdin_data;
844         pproc->incnt = stdin_data_len;
845         if (!pproc->inp) {
846                 stdin_eof = TRUE;
847                 CloseHandle((HANDLE)pproc->sv_stdin[0]);
848                 pproc->sv_stdin[0] = 0;
849         } else {
850                 tStdin = (HANDLE) _beginthreadex( 0, 1024,
851                         (unsigned (__stdcall *) (void *))proc_stdin_thread,
852                                                   pproc, 0, &dwStdin);
853                 if (tStdin == 0) {
854                         pproc->last_err = GetLastError();
855                         pproc->lerrno = E_SCALL;
856                         goto done;
857                 }
858         }
859
860         /*
861          *   Assume child will produce stdout and stderr
862          */
863         tStdout = (HANDLE) _beginthreadex( 0, 1024,
864                 (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0,
865                 &dwStdout);
866         tStderr = (HANDLE) _beginthreadex( 0, 1024,
867                 (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,
868                 &dwStderr);
869
870         if (tStdout == 0 || tStderr == 0) {
871
872                 pproc->last_err = GetLastError();
873                 pproc->lerrno = E_SCALL;
874                 goto done;
875         }
876
877
878         /*
879          *  Wait for all I/O to finish and for the child process to exit
880          */
881
882         while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {
883                 wait_count = 0;
884                 if (!stdin_eof) {
885                         wait_list[wait_count++] = tStdin;
886                 }
887                 if (!stdout_eof) {
888                         wait_list[wait_count++] = tStdout;
889                 }
890                 if (!stderr_eof) {
891                         wait_list[wait_count++] = tStderr;
892                 }
893                 if (!child_dead) {
894                         wait_list[wait_count++] = childhand;
895                 }
896
897                 wait_return = WaitForMultipleObjects(wait_count, wait_list,
898                          FALSE, /* don't wait for all: one ready will do */
899                          child_dead? 1000 :INFINITE); /* after the child dies, subthreads have
900                                 one second to collect all remaining output */
901
902                 if (wait_return == WAIT_FAILED) {
903 /*                      map_windows32_error_to_string(GetLastError());*/
904                         pproc->last_err = GetLastError();
905                         pproc->lerrno = E_SCALL;
906                         goto done;
907                 }
908
909                 ready_hand = wait_list[wait_return - WAIT_OBJECT_0];
910
911                 if (ready_hand == tStdin) {
912                         CloseHandle((HANDLE)pproc->sv_stdin[0]);
913                         pproc->sv_stdin[0] = 0;
914                         CloseHandle(tStdin);
915                         tStdin = 0;
916                         stdin_eof = TRUE;
917
918                 } else if (ready_hand == tStdout) {
919
920                         CloseHandle((HANDLE)pproc->sv_stdout[0]);
921                         pproc->sv_stdout[0] = 0;
922                         CloseHandle(tStdout);
923                         tStdout = 0;
924                         stdout_eof = TRUE;
925
926                 } else if (ready_hand == tStderr) {
927
928                         CloseHandle((HANDLE)pproc->sv_stderr[0]);
929                         pproc->sv_stderr[0] = 0;
930                         CloseHandle(tStderr);
931                         tStderr = 0;
932                         stderr_eof = TRUE;
933
934                 } else if (ready_hand == childhand) {
935
936                         DWORD ierr;
937                         GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
938                         if (ierr == CONTROL_C_EXIT) {
939                                 pproc->signal = SIGINT;
940                         } else {
941                                 pproc->exit_code = ierr;
942                         }
943                         if (GetExitCodeResult == FALSE) {
944                                 pproc->last_err = GetLastError();
945                                 pproc->lerrno = E_SCALL;
946                                 goto done;
947                         }
948                         child_dead = TRUE;
949
950                 } else {
951
952                         /* ?? Got back a handle we didn't query ?? */
953                         pproc->last_err = 0;
954                         pproc->lerrno = E_FAIL;
955                         goto done;
956                 }
957         }
958
959  done:
960         if (tStdin != 0)
961                 CloseHandle(tStdin);
962         if (tStdout != 0)
963                 CloseHandle(tStdout);
964         if (tStderr != 0)
965                 CloseHandle(tStderr);
966
967         if (pproc->lerrno)
968                 return(-1);
969         else
970                 return(0);
971
972 }
973
974 /*
975  * Purpose: collects output from child process and returns results
976  *
977  * Description:
978  *
979  * Returns:
980  *
981  * Notes/Dependencies:
982  */
983         long
984 process_file_io(
985         HANDLE proc)
986 {
987         sub_process *pproc;
988         HANDLE childhand;
989         DWORD wait_return;
990         BOOL GetExitCodeResult;
991         DWORD ierr;
992
993         if (proc == NULL)
994                 pproc = process_wait_for_any_private(1, 0);
995         else
996                 pproc = (sub_process *)proc;
997
998         /* some sort of internal error */
999         if (!pproc)
1000                 return -1;
1001
1002         childhand = (HANDLE) pproc->pid;
1003
1004         /*
1005          * This function is poorly named, and could also be used just to wait
1006          * for child death if you're doing your own pipe I/O.  If that is
1007          * the case, close the pipe handles here.
1008          */
1009         if (pproc->sv_stdin[0]) {
1010                 CloseHandle((HANDLE)pproc->sv_stdin[0]);
1011                 pproc->sv_stdin[0] = 0;
1012         }
1013         if (pproc->sv_stdout[0]) {
1014                 CloseHandle((HANDLE)pproc->sv_stdout[0]);
1015                 pproc->sv_stdout[0] = 0;
1016         }
1017         if (pproc->sv_stderr[0]) {
1018                 CloseHandle((HANDLE)pproc->sv_stderr[0]);
1019                 pproc->sv_stderr[0] = 0;
1020         }
1021
1022         /*
1023          *  Wait for the child process to exit
1024          */
1025
1026         wait_return = WaitForSingleObject(childhand, INFINITE);
1027
1028         if (wait_return != WAIT_OBJECT_0) {
1029 /*              map_windows32_error_to_string(GetLastError());*/
1030                 pproc->last_err = GetLastError();
1031                 pproc->lerrno = E_SCALL;
1032                 goto done2;
1033         }
1034
1035         GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
1036         if (ierr == CONTROL_C_EXIT) {
1037                 pproc->signal = SIGINT;
1038         } else {
1039                 pproc->exit_code = ierr;
1040         }
1041         if (GetExitCodeResult == FALSE) {
1042                 pproc->last_err = GetLastError();
1043                 pproc->lerrno = E_SCALL;
1044         }
1045
1046 done2:
1047         if (pproc->lerrno)
1048                 return(-1);
1049         else
1050                 return(0);
1051
1052 }
1053
1054 /*
1055  * Description:  Clean up any leftover handles, etc.  It is up to the
1056  * caller to manage and free the input, ouput, and stderr buffers.
1057  */
1058         void
1059 process_cleanup(
1060         HANDLE proc)
1061 {
1062         sub_process *pproc = (sub_process *)proc;
1063         int i;
1064
1065         if (pproc->using_pipes) {
1066                 for (i= 0; i <= 1; i++) {
1067                         if ((HANDLE)pproc->sv_stdin[i])
1068                                 CloseHandle((HANDLE)pproc->sv_stdin[i]);
1069                         if ((HANDLE)pproc->sv_stdout[i])
1070                                 CloseHandle((HANDLE)pproc->sv_stdout[i]);
1071                         if ((HANDLE)pproc->sv_stderr[i])
1072                                 CloseHandle((HANDLE)pproc->sv_stderr[i]);
1073                 }
1074         }
1075         if ((HANDLE)pproc->pid)
1076                 CloseHandle((HANDLE)pproc->pid);
1077
1078         free(pproc);
1079 }
1080
1081
1082 /*
1083  * Description:
1084  *       Create a command line buffer to pass to CreateProcess
1085  *
1086  * Returns:  the buffer or NULL for failure
1087  *      Shell case:  sh_name a:/full/path/to/script argv[1] argv[2] ...
1088  *  Otherwise:   argv[0] argv[1] argv[2] ...
1089  *
1090  * Notes/Dependencies:
1091  *   CreateProcess does not take an argv, so this command creates a
1092  *   command line for the executable.
1093  */
1094
1095 static char *
1096 make_command_line( char *shell_name, char *full_exec_path, char **argv)
1097 {
1098         int             argc = 0;
1099         char**          argvi;
1100         int*            enclose_in_quotes = NULL;
1101         int*            enclose_in_quotes_i;
1102         unsigned int    bytes_required = 0;
1103         char*           command_line;
1104         char*           command_line_i;
1105         int  cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */
1106         int have_sh = 0; /* HAVE_CYGWIN_SHELL */
1107
1108 #ifdef HAVE_CYGWIN_SHELL
1109         have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe"));
1110         cygwin_mode = 1;
1111 #endif
1112
1113         if (shell_name && full_exec_path) {
1114                 bytes_required
1115                   = strlen(shell_name) + 1 + strlen(full_exec_path);
1116                 /*
1117                  * Skip argv[0] if any, when shell_name is given.
1118                  */
1119                 if (*argv) argv++;
1120                 /*
1121                  * Add one for the intervening space.
1122                  */
1123                 if (*argv) bytes_required++;
1124         }
1125
1126         argvi = argv;
1127         while (*(argvi++)) argc++;
1128
1129         if (argc) {
1130                 enclose_in_quotes = (int*) calloc(1, argc * sizeof(int));
1131
1132                 if (!enclose_in_quotes) {
1133                         return NULL;
1134                 }
1135         }
1136
1137         /* We have to make one pass through each argv[i] to see if we need
1138          * to enclose it in ", so we might as well figure out how much
1139          * memory we'll need on the same pass.
1140          */
1141
1142         argvi = argv;
1143         enclose_in_quotes_i = enclose_in_quotes;
1144         while(*argvi) {
1145                 char* p = *argvi;
1146                 unsigned int backslash_count = 0;
1147
1148                 /*
1149                  * We have to enclose empty arguments in ".
1150                  */
1151                 if (!(*p)) *enclose_in_quotes_i = 1;
1152
1153                 while(*p) {
1154                         switch (*p) {
1155                         case '\"':
1156                                 /*
1157                                  * We have to insert a backslash for each "
1158                                  * and each \ that precedes the ".
1159                                  */
1160                                 bytes_required += (backslash_count + 1);
1161                                 backslash_count = 0;
1162                                 break;
1163
1164 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1165                         case '\\':
1166                                 backslash_count++;
1167                                 break;
1168 #endif
1169         /*
1170          * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
1171          * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
1172          * that argv in always equals argv out. This was removed.  Say you have
1173          * such a program named glob.exe.  You enter
1174          * glob '*'
1175          * at the sh command prompt.  Obviously the intent is to make glob do the
1176          * wildcarding instead of sh.  If we set *enclose_in_quotes_i for '*' or '?',
1177          * then the command line that glob would see would be
1178          * glob "*"
1179          * and the _setargv in SETARGV.OBJ would _not_ expand the *.
1180          */
1181                         case ' ':
1182                         case '\t':
1183                                 *enclose_in_quotes_i = 1;
1184                                 /* fall through */
1185
1186                         default:
1187                                 backslash_count = 0;
1188                                 break;
1189                         }
1190
1191                         /*
1192                          * Add one for each character in argv[i].
1193                          */
1194                         bytes_required++;
1195
1196                         p++;
1197                 }
1198
1199                 if (*enclose_in_quotes_i) {
1200                         /*
1201                          * Add one for each enclosing ",
1202                          * and one for each \ that precedes the
1203                          * closing ".
1204                          */
1205                         bytes_required += (backslash_count + 2);
1206                 }
1207
1208                 /*
1209                  * Add one for the intervening space.
1210                  */
1211                 if (*(++argvi)) bytes_required++;
1212                 enclose_in_quotes_i++;
1213         }
1214
1215         /*
1216          * Add one for the terminating NULL.
1217          */
1218         bytes_required++;
1219
1220         command_line = (char*) malloc(bytes_required);
1221
1222         if (!command_line) {
1223                 if (enclose_in_quotes) free(enclose_in_quotes);
1224                 return NULL;
1225         }
1226
1227         command_line_i = command_line;
1228
1229         if (shell_name && full_exec_path) {
1230                 while(*shell_name) {
1231                         *(command_line_i++) = *(shell_name++);
1232                 }
1233
1234                 *(command_line_i++) = ' ';
1235
1236                 while(*full_exec_path) {
1237                         *(command_line_i++) = *(full_exec_path++);
1238                 }
1239
1240                 if (*argv) {
1241                         *(command_line_i++) = ' ';
1242                 }
1243         }
1244
1245         argvi = argv;
1246         enclose_in_quotes_i = enclose_in_quotes;
1247
1248         while(*argvi) {
1249                 char* p = *argvi;
1250                 unsigned int backslash_count = 0;
1251
1252                 if (*enclose_in_quotes_i) {
1253                         *(command_line_i++) = '\"';
1254                 }
1255
1256                 while(*p) {
1257                         if (*p == '\"') {
1258                                 if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */
1259                                         /* instead of a \", cygwin likes "" */
1260                                         *(command_line_i++) = '\"';
1261                                 } else {
1262
1263                                 /*
1264                                  * We have to insert a backslash for the "
1265                                  * and each \ that precedes the ".
1266                                  */
1267                                 backslash_count++;
1268
1269                                 while(backslash_count) {
1270                                         *(command_line_i++) = '\\';
1271                                         backslash_count--;
1272                                 };
1273                                 }
1274 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1275                         } else if (*p == '\\') {
1276                                 backslash_count++;
1277                         } else {
1278                                 backslash_count = 0;
1279 #endif
1280                         }
1281
1282                         /*
1283                          * Copy the character.
1284                          */
1285                         *(command_line_i++) = *(p++);
1286                 }
1287
1288                 if (*enclose_in_quotes_i) {
1289 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1290                         /*
1291                          * Add one \ for each \ that precedes the
1292                          * closing ".
1293                          */
1294                         while(backslash_count--) {
1295                                 *(command_line_i++) = '\\';
1296                         };
1297 #endif
1298                         *(command_line_i++) = '\"';
1299                 }
1300
1301                 /*
1302                  * Append an intervening space.
1303                  */
1304                 if (*(++argvi)) {
1305                         *(command_line_i++) = ' ';
1306                 }
1307
1308                 enclose_in_quotes_i++;
1309         }
1310
1311         /*
1312          * Append the terminating NULL.
1313          */
1314         *command_line_i = '\0';
1315
1316         if (enclose_in_quotes) free(enclose_in_quotes);
1317         return command_line;
1318 }
1319
1320 /*
1321  * Description: Given an argv and optional envp, launch the process
1322  *              using the default stdin, stdout, and stderr handles.
1323  *              Also, register process so that process_wait_for_any_private()
1324  *              can be used via process_file_io(NULL) or
1325  *              process_wait_for_any().
1326  *
1327  * Returns:
1328  *
1329  * Notes/Dependencies:
1330  */
1331 HANDLE
1332 process_easy(
1333         char **argv,
1334         char **envp)
1335 {
1336   HANDLE hIn;
1337   HANDLE hOut;
1338   HANDLE hErr;
1339   HANDLE hProcess;
1340
1341   if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
1342         DB (DB_JOBS, ("process_easy: All process slots used up\n"));
1343         return INVALID_HANDLE_VALUE;
1344   }
1345   if (DuplicateHandle(GetCurrentProcess(),
1346                       GetStdHandle(STD_INPUT_HANDLE),
1347                       GetCurrentProcess(),
1348                       &hIn,
1349                       0,
1350                       TRUE,
1351                       DUPLICATE_SAME_ACCESS) == FALSE) {
1352     fprintf(stderr,
1353             "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
1354             GetLastError());
1355     return INVALID_HANDLE_VALUE;
1356   }
1357   if (DuplicateHandle(GetCurrentProcess(),
1358                       GetStdHandle(STD_OUTPUT_HANDLE),
1359                       GetCurrentProcess(),
1360                       &hOut,
1361                       0,
1362                       TRUE,
1363                       DUPLICATE_SAME_ACCESS) == FALSE) {
1364     fprintf(stderr,
1365            "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
1366            GetLastError());
1367     return INVALID_HANDLE_VALUE;
1368   }
1369   if (DuplicateHandle(GetCurrentProcess(),
1370                       GetStdHandle(STD_ERROR_HANDLE),
1371                       GetCurrentProcess(),
1372                       &hErr,
1373                       0,
1374                       TRUE,
1375                       DUPLICATE_SAME_ACCESS) == FALSE) {
1376     fprintf(stderr,
1377             "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
1378             GetLastError());
1379     return INVALID_HANDLE_VALUE;
1380   }
1381
1382   hProcess = process_init_fd(hIn, hOut, hErr);
1383
1384   if (process_begin(hProcess, argv, envp, argv[0], NULL)) {
1385     fake_exits_pending++;
1386     /* process_begin() failed: make a note of that.  */
1387     if (!((sub_process*) hProcess)->last_err)
1388       ((sub_process*) hProcess)->last_err = -1;
1389     ((sub_process*) hProcess)->exit_code = process_last_err(hProcess);
1390
1391     /* close up unused handles */
1392     CloseHandle(hIn);
1393     CloseHandle(hOut);
1394     CloseHandle(hErr);
1395   }
1396
1397   process_register(hProcess);
1398
1399   return hProcess;
1400 }