1 /* Process handling for Windows.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 This file is part of GNU Make.
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
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.
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/>. */
22 # include <stddef.h> /* for intptr_t */
26 #include <process.h> /* for msvc _beginthreadex, _endthreadex */
35 static char *make_command_line(char *shell_name
, char *exec_path
, char **argv
);
36 extern char *xmalloc (unsigned int);
38 typedef struct sub_process_t
{
40 intptr_t sv_stdout
[2];
41 intptr_t sv_stderr
[2];
46 volatile DWORD outcnt
;
48 volatile DWORD errcnt
;
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;
61 /* Windows jobserver implementation variables */
62 static char jobserver_semaphore_name
[MAX_PATH
+ 1];
63 static HANDLE jobserver_semaphore
= NULL
;
65 /* Open existing jobserver semaphore */
66 int open_jobserver_semaphore(const char* name
)
68 jobserver_semaphore
= OpenSemaphore(
69 SEMAPHORE_ALL_ACCESS
, // Semaphore access setting
70 FALSE
, // Child processes DON'T inherit
71 name
); // Semaphore name
73 if (jobserver_semaphore
== NULL
)
79 /* Create new jobserver semaphore */
80 int create_jobserver_semaphore(int tokens
)
82 sprintf(jobserver_semaphore_name
, "gmake_semaphore_%d", _getpid());
84 jobserver_semaphore
= CreateSemaphore(
85 NULL
, // Use default security descriptor
86 tokens
, // Initial count
87 tokens
, // Maximum count
88 jobserver_semaphore_name
); // Semaphore name
90 if (jobserver_semaphore
== NULL
)
96 /* Close jobserver semaphore */
97 void free_jobserver_semaphore()
99 if (jobserver_semaphore
!= NULL
)
101 CloseHandle(jobserver_semaphore
);
102 jobserver_semaphore
= NULL
;
106 /* Decrement semaphore count */
107 int acquire_jobserver_semaphore()
109 DWORD dwEvent
= WaitForSingleObject(
110 jobserver_semaphore
, // Handle to semaphore
111 0); // DON'T wait on semaphore
113 return (dwEvent
== WAIT_OBJECT_0
);
116 /* Increment semaphore count */
117 int release_jobserver_semaphore()
119 BOOL bResult
= ReleaseSemaphore(
120 jobserver_semaphore
, // handle to semaphore
121 1, // increase count by one
122 NULL
); // not interested in previous count
127 int has_jobserver_semaphore()
129 return (jobserver_semaphore
!= NULL
);
132 char* get_jobserver_semaphore_name()
134 return (jobserver_semaphore_name
);
137 /* Wait for either the jobserver semaphore to become signalled or one of our
138 * child processes to terminate.
140 int wait_for_semaphore_or_child_process()
142 HANDLE handles
[MAXIMUM_WAIT_OBJECTS
];
143 DWORD dwHandleCount
= 1;
147 /* Add jobserver semaphore to first slot. */
148 handles
[0] = jobserver_semaphore
;
150 /* Build array of handles to wait for */
151 for (i
= 0; i
< proc_index
; i
++)
153 /* Don't wait on child processes that have already finished */
154 if (fake_exits_pending
&& proc_array
[i
]->exit_code
)
157 handles
[dwHandleCount
++] = (HANDLE
) proc_array
[i
]->pid
;
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
172 /* Indicate that the semaphore was signalled */
176 /* Assume that one or more of the child processes terminated. */
182 * When a process has been waited for, adjust the wait state
183 * array so that we don't wait for it again
186 process_adjust_wait_state(sub_process
* pproc
)
193 for (i
= 0; i
< proc_index
; i
++)
194 if (proc_array
[i
]->pid
== pproc
->pid
)
197 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
;
207 * Waits for any of the registered child processes to finish.
210 process_wait_for_any_private(int block
, DWORD
* pdwWaitStatus
)
212 HANDLE handles
[MAXIMUM_WAIT_OBJECTS
];
219 /* build array of handles to wait for */
220 for (i
= 0; i
< proc_index
; i
++) {
221 handles
[i
] = (HANDLE
) proc_array
[i
]->pid
;
223 if (fake_exits_pending
&& proc_array
[i
]->exit_code
)
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
;
232 fake_exits_pending
--;
233 retval
= !WAIT_FAILED
;
237 /* If the pointer is not NULL, set the wait status result variable. */
239 *pdwWaitStatus
= retval
;
241 /* return pointer to process */
242 if ((retval
== WAIT_TIMEOUT
) || (retval
== WAIT_FAILED
)) {
246 sub_process
* pproc
= proc_array
[which
];
247 process_adjust_wait_state(pproc
);
253 * Terminate a process.
256 process_kill(HANDLE proc
, int signal
)
258 sub_process
* pproc
= (sub_process
*) proc
;
259 pproc
->signal
= signal
;
260 return (TerminateProcess((HANDLE
) pproc
->pid
, signal
));
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 :-(
270 process_register(HANDLE proc
)
272 if (proc_index
< MAXIMUM_WAIT_OBJECTS
)
273 proc_array
[proc_index
++] = (sub_process
*) proc
;
277 * Return the number of processes that we are still waiting for.
280 process_used_slots(void)
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:
290 * x = process_easy(...);
294 * x = process_init_fd();
295 * process_register(x);
299 * x = process_init();
300 * process_register(x);
302 * You must NOT then call process_pipe_io() because this function is
303 * not capable of handling automatic notification of any child
308 process_wait_for_any(int block
, DWORD
* pdwWaitStatus
)
310 sub_process
* pproc
= process_wait_for_any_private(block
, pdwWaitStatus
);
316 * Ouch! can't tell caller if this fails directly. Caller
317 * will have to use process_last_err()
319 (void) process_file_io(pproc
);
320 return ((HANDLE
) pproc
);
325 process_signal(HANDLE proc
)
327 if (proc
== INVALID_HANDLE_VALUE
) return 0;
328 return (((sub_process
*)proc
)->signal
);
332 process_last_err(HANDLE proc
)
334 if (proc
== INVALID_HANDLE_VALUE
) return ERROR_INVALID_HANDLE
;
335 return (((sub_process
*)proc
)->last_err
);
339 process_exit_code(HANDLE proc
)
341 if (proc
== INVALID_HANDLE_VALUE
) return EXIT_FAILURE
;
342 return (((sub_process
*)proc
)->exit_code
);
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.
353 process_outbuf(HANDLE proc)
355 return (((sub_process *)proc)->outp);
359 process_errbuf(HANDLE proc)
361 return (((sub_process *)proc)->errp);
365 process_outcnt(HANDLE proc)
367 return (((sub_process *)proc)->outcnt);
371 process_errcnt(HANDLE proc)
373 return (((sub_process *)proc)->errcnt);
377 process_pipes(HANDLE proc, int pipes[3])
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];
391 * open file descriptors for attaching stdin/stdout/sterr
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
];
399 pproc
= malloc(sizeof(*pproc
));
400 memset(pproc
, 0, sizeof(*pproc
));
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. */
407 if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR
)(&sd
),
408 SECURITY_DESCRIPTOR_REVISION
)) {
409 pproc
->last_err
= GetLastError();
410 pproc
->lerrno
= E_SCALL
;
411 return((HANDLE
)pproc
);
414 inherit
.nLength
= sizeof(inherit
);
415 inherit
.lpSecurityDescriptor
= (PSECURITY_DESCRIPTOR
)(&sd
);
416 inherit
.bInheritHandle
= TRUE
;
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
) {
425 pproc
->last_err
= GetLastError();
426 pproc
->lerrno
= E_SCALL
;
427 return((HANDLE
)pproc
);
431 // Mark the parent sides of the pipes as non-inheritable
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
) {
440 pproc
->last_err
= GetLastError();
441 pproc
->lerrno
= E_SCALL
;
442 return((HANDLE
)pproc
);
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];
451 pproc
->using_pipes
= 1;
455 return((HANDLE
)pproc
);
460 process_init_fd(HANDLE stdinh
, HANDLE stdouth
, HANDLE stderrh
)
464 pproc
= malloc(sizeof(*pproc
));
465 memset(pproc
, 0, sizeof(*pproc
));
468 * Just pass the provided file handles to the 'child side' of the
469 * pipe, bypassing pipes altogether.
471 pproc
->sv_stdin
[1] = (intptr_t) stdinh
;
472 pproc
->sv_stdout
[1] = (intptr_t) stdouth
;
473 pproc
->sv_stderr
[1] = (intptr_t) stderrh
;
475 pproc
->last_err
= pproc
->lerrno
= 0;
477 return((HANDLE
)pproc
);
482 find_file(const char *exec_path
, const char *path_var
,
483 char *full_fname
, DWORD full_len
)
490 static const char *extensions
[] =
491 /* Should .com come before no-extension case? */
492 { ".exe", ".cmd", ".bat", "", ".com", NULL
};
494 fname
= xmalloc(strlen(exec_path
) + 5);
495 strcpy(fname
, exec_path
);
496 ext
= fname
+ strlen(fname
);
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
512 || (req_len
= SearchPath (NULL
, fname
, NULL
, full_len
,
513 full_fname
, NULL
)) > 0)
514 && req_len
<= full_len
516 CreateFile(full_fname
,
518 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
521 FILE_ATTRIBUTE_NORMAL
,
522 NULL
)) != INVALID_HANDLE_VALUE
) {
529 return INVALID_HANDLE_VALUE
;
534 * Description: Create the child process to be helped
536 * Returns: success <=> 0
538 * Notes/Dependencies:
548 sub_process
*pproc
= (sub_process
*)proc
;
549 char *shell_name
= 0;
550 int file_not_found
=0;
552 char exec_fname
[MAX_PATH
];
553 const char *path_var
= NULL
;
556 DWORD bytes_returned
;
559 STARTUPINFO startInfo
;
560 PROCESS_INFORMATION procInfo
;
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
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. */
576 for (ep
= envp
; *ep
; ep
++) {
577 if (strncmp (*ep
, "PATH=", 5) == 0
578 || strncmp (*ep
, "Path=", 5) == 0) {
583 exec_handle
= find_file(exec_path
, path_var
,
584 exec_fname
, sizeof(exec_fname
));
587 * If we couldn't open the file, just assume that Windows will be
588 * somehow able to find and execute it.
590 if (exec_handle
== INVALID_HANDLE_VALUE
) {
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) {
599 pproc
->last_err
= GetLastError();
600 pproc
->lerrno
= E_IO
;
601 CloseHandle(exec_handle
);
604 if (buf
[0] == '#' && buf
[1] == '!') {
606 * This is a shell script... Change the command line from
607 * exec_path args to shell_name exec_path args
611 /* Make sure buf is NULL terminated */
612 buf
[bytes_returned
] = 0;
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.
618 p
= strchr(buf
, '\n');
621 p
= strchr(buf
, '\r');
626 * Find base name of shell
628 shell_name
= strrchr( buf
, '/');
632 shell_name
= &buf
[2];/* skipping "#!" */
636 CloseHandle(exec_handle
);
642 command_line
= make_command_line( shell_name
, exec_path
, argv
);
644 command_line
= make_command_line( shell_name
, exec_fname
, argv
);
646 if ( command_line
== NULL
) {
648 pproc
->lerrno
= E_NO_MEM
;
653 if (arr2envblk(envp
, &envblk
) ==FALSE
) {
655 pproc
->lerrno
= E_NO_MEM
;
656 free( command_line
);
661 if ((shell_name
) || (file_not_found
)) {
662 exec_path
= 0; /* Search for the program in %Path% */
664 exec_path
= exec_fname
;
668 * Set up inherited stdin, stdout, stderr for child
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];
681 if (envblk
) free(envblk
);
684 DB (DB_JOBS
, ("CreateProcess(%s,%s,...)\n",
685 exec_path
? exec_path
: "NULL",
686 command_line
? command_line
: "NULL"));
691 0, /* default security attributes for thread */
692 TRUE
, /* inherit handles (e.g. helper pipes, oserv socket) */
695 0, /* default starting directory */
697 &procInfo
) == FALSE
) {
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
);
709 pproc
->pid
= (pid_t
)procInfo
.hProcess
;
710 /* Close the thread handle -- we'll just watch the process */
711 CloseHandle(procInfo
.hThread
);
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;
721 free( command_line
);
722 if (envblk
) free(envblk
);
730 proc_stdin_thread(sub_process
*pproc
)
734 if (WriteFile( (HANDLE
) pproc
->sv_stdin
[0], pproc
->inp
, pproc
->incnt
,
735 &in_done
, NULL
) == FALSE
)
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
;
746 return 0; // for compiler warnings only.. not reached
750 proc_stdout_thread(sub_process
*pproc
)
752 DWORD bufsize
= 1024;
755 pproc
->outp
= malloc(bufsize
);
756 if (pproc
->outp
== NULL
)
761 if (ReadFile( (HANDLE
)pproc
->sv_stdout
[0], &c
, 1, &nread
, NULL
)
763 /* map_windows32_error_to_string(GetLastError());*/
768 if (pproc
->outcnt
+ nread
> bufsize
) {
769 bufsize
+= nread
+ 512;
770 pproc
->outp
= realloc(pproc
->outp
, bufsize
);
771 if (pproc
->outp
== NULL
) {
776 pproc
->outp
[pproc
->outcnt
++] = c
;
782 proc_stderr_thread(sub_process
*pproc
)
784 DWORD bufsize
= 1024;
787 pproc
->errp
= malloc(bufsize
);
788 if (pproc
->errp
== NULL
)
793 if (ReadFile( (HANDLE
)pproc
->sv_stderr
[0], &c
, 1, &nread
, NULL
) == FALSE
) {
794 map_windows32_error_to_string(GetLastError());
799 if (pproc
->errcnt
+ nread
> bufsize
) {
800 bufsize
+= nread
+ 512;
801 pproc
->errp
= realloc(pproc
->errp
, bufsize
);
802 if (pproc
->errp
== NULL
) {
807 pproc
->errp
[pproc
->errcnt
++] = c
;
814 * Purpose: collects output from child process and returns results
820 * Notes/Dependencies:
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
;
837 bool_t child_dead
= FALSE
;
838 BOOL GetExitCodeResult
;
841 * Create stdin thread, if needed
843 pproc
->inp
= stdin_data
;
844 pproc
->incnt
= stdin_data_len
;
847 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
848 pproc
->sv_stdin
[0] = 0;
850 tStdin
= (HANDLE
) _beginthreadex( 0, 1024,
851 (unsigned (__stdcall
*) (void *))proc_stdin_thread
,
854 pproc
->last_err
= GetLastError();
855 pproc
->lerrno
= E_SCALL
;
861 * Assume child will produce stdout and stderr
863 tStdout
= (HANDLE
) _beginthreadex( 0, 1024,
864 (unsigned (__stdcall
*) (void *))proc_stdout_thread
, pproc
, 0,
866 tStderr
= (HANDLE
) _beginthreadex( 0, 1024,
867 (unsigned (__stdcall
*) (void *))proc_stderr_thread
, pproc
, 0,
870 if (tStdout
== 0 || tStderr
== 0) {
872 pproc
->last_err
= GetLastError();
873 pproc
->lerrno
= E_SCALL
;
879 * Wait for all I/O to finish and for the child process to exit
882 while (!stdin_eof
|| !stdout_eof
|| !stderr_eof
|| !child_dead
) {
885 wait_list
[wait_count
++] = tStdin
;
888 wait_list
[wait_count
++] = tStdout
;
891 wait_list
[wait_count
++] = tStderr
;
894 wait_list
[wait_count
++] = childhand
;
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 */
902 if (wait_return
== WAIT_FAILED
) {
903 /* map_windows32_error_to_string(GetLastError());*/
904 pproc
->last_err
= GetLastError();
905 pproc
->lerrno
= E_SCALL
;
909 ready_hand
= wait_list
[wait_return
- WAIT_OBJECT_0
];
911 if (ready_hand
== tStdin
) {
912 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
913 pproc
->sv_stdin
[0] = 0;
918 } else if (ready_hand
== tStdout
) {
920 CloseHandle((HANDLE
)pproc
->sv_stdout
[0]);
921 pproc
->sv_stdout
[0] = 0;
922 CloseHandle(tStdout
);
926 } else if (ready_hand
== tStderr
) {
928 CloseHandle((HANDLE
)pproc
->sv_stderr
[0]);
929 pproc
->sv_stderr
[0] = 0;
930 CloseHandle(tStderr
);
934 } else if (ready_hand
== childhand
) {
937 GetExitCodeResult
= GetExitCodeProcess(childhand
, &ierr
);
938 if (ierr
== CONTROL_C_EXIT
) {
939 pproc
->signal
= SIGINT
;
941 pproc
->exit_code
= ierr
;
943 if (GetExitCodeResult
== FALSE
) {
944 pproc
->last_err
= GetLastError();
945 pproc
->lerrno
= E_SCALL
;
952 /* ?? Got back a handle we didn't query ?? */
954 pproc
->lerrno
= E_FAIL
;
963 CloseHandle(tStdout
);
965 CloseHandle(tStderr
);
975 * Purpose: collects output from child process and returns results
981 * Notes/Dependencies:
990 BOOL GetExitCodeResult
;
994 pproc
= process_wait_for_any_private(1, 0);
996 pproc
= (sub_process
*)proc
;
998 /* some sort of internal error */
1002 childhand
= (HANDLE
) pproc
->pid
;
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.
1009 if (pproc
->sv_stdin
[0]) {
1010 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
1011 pproc
->sv_stdin
[0] = 0;
1013 if (pproc
->sv_stdout
[0]) {
1014 CloseHandle((HANDLE
)pproc
->sv_stdout
[0]);
1015 pproc
->sv_stdout
[0] = 0;
1017 if (pproc
->sv_stderr
[0]) {
1018 CloseHandle((HANDLE
)pproc
->sv_stderr
[0]);
1019 pproc
->sv_stderr
[0] = 0;
1023 * Wait for the child process to exit
1026 wait_return
= WaitForSingleObject(childhand
, INFINITE
);
1028 if (wait_return
!= WAIT_OBJECT_0
) {
1029 /* map_windows32_error_to_string(GetLastError());*/
1030 pproc
->last_err
= GetLastError();
1031 pproc
->lerrno
= E_SCALL
;
1035 GetExitCodeResult
= GetExitCodeProcess(childhand
, &ierr
);
1036 if (ierr
== CONTROL_C_EXIT
) {
1037 pproc
->signal
= SIGINT
;
1039 pproc
->exit_code
= ierr
;
1041 if (GetExitCodeResult
== FALSE
) {
1042 pproc
->last_err
= GetLastError();
1043 pproc
->lerrno
= E_SCALL
;
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.
1062 sub_process
*pproc
= (sub_process
*)proc
;
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
]);
1075 if ((HANDLE
)pproc
->pid
)
1076 CloseHandle((HANDLE
)pproc
->pid
);
1084 * Create a command line buffer to pass to CreateProcess
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] ...
1090 * Notes/Dependencies:
1091 * CreateProcess does not take an argv, so this command creates a
1092 * command line for the executable.
1096 make_command_line( char *shell_name
, char *full_exec_path
, char **argv
)
1100 int* enclose_in_quotes
= NULL
;
1101 int* enclose_in_quotes_i
;
1102 unsigned int bytes_required
= 0;
1104 char* command_line_i
;
1105 int cygwin_mode
= 0; /* HAVE_CYGWIN_SHELL */
1106 int have_sh
= 0; /* HAVE_CYGWIN_SHELL */
1108 #ifdef HAVE_CYGWIN_SHELL
1109 have_sh
= (shell_name
!= NULL
|| strstr(full_exec_path
, "sh.exe"));
1113 if (shell_name
&& full_exec_path
) {
1115 = strlen(shell_name
) + 1 + strlen(full_exec_path
);
1117 * Skip argv[0] if any, when shell_name is given.
1121 * Add one for the intervening space.
1123 if (*argv
) bytes_required
++;
1127 while (*(argvi
++)) argc
++;
1130 enclose_in_quotes
= (int*) calloc(1, argc
* sizeof(int));
1132 if (!enclose_in_quotes
) {
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.
1143 enclose_in_quotes_i
= enclose_in_quotes
;
1146 unsigned int backslash_count
= 0;
1149 * We have to enclose empty arguments in ".
1151 if (!(*p
)) *enclose_in_quotes_i
= 1;
1157 * We have to insert a backslash for each "
1158 * and each \ that precedes the ".
1160 bytes_required
+= (backslash_count
+ 1);
1161 backslash_count
= 0;
1164 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
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
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
1179 * and the _setargv in SETARGV.OBJ would _not_ expand the *.
1183 *enclose_in_quotes_i
= 1;
1187 backslash_count
= 0;
1192 * Add one for each character in argv[i].
1199 if (*enclose_in_quotes_i
) {
1201 * Add one for each enclosing ",
1202 * and one for each \ that precedes the
1205 bytes_required
+= (backslash_count
+ 2);
1209 * Add one for the intervening space.
1211 if (*(++argvi
)) bytes_required
++;
1212 enclose_in_quotes_i
++;
1216 * Add one for the terminating NULL.
1220 command_line
= (char*) malloc(bytes_required
);
1222 if (!command_line
) {
1223 if (enclose_in_quotes
) free(enclose_in_quotes
);
1227 command_line_i
= command_line
;
1229 if (shell_name
&& full_exec_path
) {
1230 while(*shell_name
) {
1231 *(command_line_i
++) = *(shell_name
++);
1234 *(command_line_i
++) = ' ';
1236 while(*full_exec_path
) {
1237 *(command_line_i
++) = *(full_exec_path
++);
1241 *(command_line_i
++) = ' ';
1246 enclose_in_quotes_i
= enclose_in_quotes
;
1250 unsigned int backslash_count
= 0;
1252 if (*enclose_in_quotes_i
) {
1253 *(command_line_i
++) = '\"';
1258 if (cygwin_mode
&& have_sh
) { /* HAVE_CYGWIN_SHELL */
1259 /* instead of a \", cygwin likes "" */
1260 *(command_line_i
++) = '\"';
1264 * We have to insert a backslash for the "
1265 * and each \ that precedes the ".
1269 while(backslash_count
) {
1270 *(command_line_i
++) = '\\';
1274 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1275 } else if (*p
== '\\') {
1278 backslash_count
= 0;
1283 * Copy the character.
1285 *(command_line_i
++) = *(p
++);
1288 if (*enclose_in_quotes_i
) {
1289 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1291 * Add one \ for each \ that precedes the
1294 while(backslash_count
--) {
1295 *(command_line_i
++) = '\\';
1298 *(command_line_i
++) = '\"';
1302 * Append an intervening space.
1305 *(command_line_i
++) = ' ';
1308 enclose_in_quotes_i
++;
1312 * Append the terminating NULL.
1314 *command_line_i
= '\0';
1316 if (enclose_in_quotes
) free(enclose_in_quotes
);
1317 return command_line
;
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().
1329 * Notes/Dependencies:
1341 if (proc_index
>= MAXIMUM_WAIT_OBJECTS
) {
1342 DB (DB_JOBS
, ("process_easy: All process slots used up\n"));
1343 return INVALID_HANDLE_VALUE
;
1345 if (DuplicateHandle(GetCurrentProcess(),
1346 GetStdHandle(STD_INPUT_HANDLE
),
1347 GetCurrentProcess(),
1351 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1353 "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
1355 return INVALID_HANDLE_VALUE
;
1357 if (DuplicateHandle(GetCurrentProcess(),
1358 GetStdHandle(STD_OUTPUT_HANDLE
),
1359 GetCurrentProcess(),
1363 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1365 "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
1367 return INVALID_HANDLE_VALUE
;
1369 if (DuplicateHandle(GetCurrentProcess(),
1370 GetStdHandle(STD_ERROR_HANDLE
),
1371 GetCurrentProcess(),
1375 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1377 "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
1379 return INVALID_HANDLE_VALUE
;
1382 hProcess
= process_init_fd(hIn
, hOut
, hErr
);
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
);
1391 /* close up unused handles */
1397 process_register(hProcess
);