1 /* Process handling for Windows.
2 Copyright (C) 1996-2016 Free Software Foundation, Inc.
3 This file is part of GNU Make.
5 GNU Make is free software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the Free Software
7 Foundation; either version 3 of the License, or (at your option) any later
10 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along with
15 this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include <io.h> /* for _get_osfhandle */
22 # include <stddef.h> /* for intptr_t */
27 #include <process.h> /* for msvc _beginthreadex, _endthreadex */
39 static char *make_command_line(char *shell_name, char *exec_path, char **argv);
41 typedef struct sub_process_t {
43 intptr_t sv_stdout[2];
44 intptr_t sv_stderr[2];
49 volatile DWORD outcnt;
51 volatile DWORD errcnt;
59 /* keep track of children so we can implement a waitpid-like routine */
60 static sub_process *proc_array[MAXIMUM_WAIT_OBJECTS];
61 static int proc_index = 0;
62 static int fake_exits_pending = 0;
66 * Fill a HANDLE list with handles to wait for.
69 process_set_handles(HANDLE *handles)
74 /* Build array of handles to wait for */
75 for (i = 0; i < proc_index; i++) {
76 /* Don't wait on child processes that have already finished */
77 if (fake_exits_pending && proc_array[i]->exit_code)
80 handles[count++] = (HANDLE) proc_array[i]->pid;
87 * When a process has been waited for, adjust the wait state
88 * array so that we don't wait for it again
91 process_adjust_wait_state(sub_process* pproc)
98 for (i = 0; i < proc_index; i++)
99 if (proc_array[i]->pid == pproc->pid)
102 if (i < proc_index) {
105 memmove(&proc_array[i], &proc_array[i+1],
106 (proc_index-i) * sizeof(sub_process*));
107 proc_array[proc_index] = NULL;
112 * Waits for any of the registered child processes to finish.
115 process_wait_for_any_private(int block, DWORD* pdwWaitStatus)
117 HANDLE handles[MAXIMUM_WAIT_OBJECTS];
124 /* build array of handles to wait for */
125 for (i = 0; i < proc_index; i++) {
126 handles[i] = (HANDLE) proc_array[i]->pid;
128 if (fake_exits_pending && proc_array[i]->exit_code)
132 /* wait for someone to exit */
133 if (!fake_exits_pending) {
134 retval = WaitForMultipleObjects(proc_index, handles, FALSE, (block ? INFINITE : 0));
135 which = retval - WAIT_OBJECT_0;
137 fake_exits_pending--;
138 retval = !WAIT_FAILED;
142 /* If the pointer is not NULL, set the wait status result variable. */
144 *pdwWaitStatus = retval;
146 /* return pointer to process */
147 if ((retval == WAIT_TIMEOUT) || (retval == WAIT_FAILED)) {
151 sub_process* pproc = proc_array[which];
152 process_adjust_wait_state(pproc);
158 * Terminate a process.
161 process_kill(HANDLE proc, int signal)
163 sub_process* pproc = (sub_process*) proc;
164 pproc->signal = signal;
165 return (TerminateProcess((HANDLE) pproc->pid, signal));
169 * Use this function to register processes you wish to wait for by
170 * calling process_file_io(NULL) or process_wait_any(). This must be done
171 * because it is possible for callers of this library to reuse the same
172 * handle for multiple processes launches :-(
175 process_register(HANDLE proc)
177 if (proc_index < MAXIMUM_WAIT_OBJECTS)
178 proc_array[proc_index++] = (sub_process *) proc;
182 * Return the number of processes that we are still waiting for.
185 process_used_slots(void)
191 * Public function which works kind of like waitpid(). Wait for any
192 * of the children to die and return results. To call this function,
193 * you must do 1 of things:
195 * x = process_easy(...);
199 * x = process_init_fd();
200 * process_register(x);
204 * x = process_init();
205 * process_register(x);
207 * You must NOT then call process_pipe_io() because this function is
208 * not capable of handling automatic notification of any child
213 process_wait_for_any(int block, DWORD* pdwWaitStatus)
215 sub_process* pproc = process_wait_for_any_private(block, pdwWaitStatus);
221 * Ouch! can't tell caller if this fails directly. Caller
222 * will have to use process_last_err()
224 (void) process_file_io(pproc);
225 return ((HANDLE) pproc);
230 process_signal(HANDLE proc)
232 if (proc == INVALID_HANDLE_VALUE) return 0;
233 return (((sub_process *)proc)->signal);
237 process_last_err(HANDLE proc)
239 if (proc == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
240 return (((sub_process *)proc)->last_err);
244 process_exit_code(HANDLE proc)
246 if (proc == INVALID_HANDLE_VALUE) return EXIT_FAILURE;
247 return (((sub_process *)proc)->exit_code);
251 process_noinherit(int fd)
253 HANDLE fh = (HANDLE)_get_osfhandle(fd);
255 if (fh && fh != INVALID_HANDLE_VALUE)
256 SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0);
261 All the following functions are currently unused.
262 All of them would crash gmake if called with argument INVALID_HANDLE_VALUE.
263 Hence whoever wants to use one of this functions must invent and implement
264 a reasonable error handling for this function.
267 process_outbuf(HANDLE proc)
269 return (((sub_process *)proc)->outp);
273 process_errbuf(HANDLE proc)
275 return (((sub_process *)proc)->errp);
279 process_outcnt(HANDLE proc)
281 return (((sub_process *)proc)->outcnt);
285 process_errcnt(HANDLE proc)
287 return (((sub_process *)proc)->errcnt);
291 process_pipes(HANDLE proc, int pipes[3])
293 pipes[0] = ((sub_process *)proc)->sv_stdin[0];
294 pipes[1] = ((sub_process *)proc)->sv_stdout[0];
295 pipes[2] = ((sub_process *)proc)->sv_stderr[0];
305 * open file descriptors for attaching stdin/stdout/sterr
307 HANDLE stdin_pipes[2];
308 HANDLE stdout_pipes[2];
309 HANDLE stderr_pipes[2];
310 SECURITY_ATTRIBUTES inherit;
311 BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
313 pproc = malloc(sizeof(*pproc));
314 memset(pproc, 0, sizeof(*pproc));
316 /* We can't use NULL for lpSecurityDescriptor because that
317 uses the default security descriptor of the calling process.
318 Instead we use a security descriptor with no DACL. This
319 allows nonrestricted access to the associated objects. */
321 if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd),
322 SECURITY_DESCRIPTOR_REVISION)) {
323 pproc->last_err = GetLastError();
324 pproc->lerrno = E_SCALL;
325 return((HANDLE)pproc);
328 inherit.nLength = sizeof(inherit);
329 inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd);
330 inherit.bInheritHandle = TRUE;
332 // By convention, parent gets pipe[0], and child gets pipe[1]
333 // This means the READ side of stdin pipe goes into pipe[1]
334 // and the WRITE side of the stdout and stderr pipes go into pipe[1]
335 if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE ||
336 CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE ||
337 CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) {
339 pproc->last_err = GetLastError();
340 pproc->lerrno = E_SCALL;
341 return((HANDLE)pproc);
345 // Mark the parent sides of the pipes as non-inheritable
347 if (SetHandleInformation(stdin_pipes[0],
348 HANDLE_FLAG_INHERIT, 0) == FALSE ||
349 SetHandleInformation(stdout_pipes[0],
350 HANDLE_FLAG_INHERIT, 0) == FALSE ||
351 SetHandleInformation(stderr_pipes[0],
352 HANDLE_FLAG_INHERIT, 0) == FALSE) {
354 pproc->last_err = GetLastError();
355 pproc->lerrno = E_SCALL;
356 return((HANDLE)pproc);
358 pproc->sv_stdin[0] = (intptr_t) stdin_pipes[0];
359 pproc->sv_stdin[1] = (intptr_t) stdin_pipes[1];
360 pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0];
361 pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1];
362 pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0];
363 pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1];
365 pproc->using_pipes = 1;
369 return((HANDLE)pproc);
374 process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
378 pproc = malloc(sizeof(*pproc));
380 memset(pproc, 0, sizeof(*pproc));
383 * Just pass the provided file handles to the 'child
384 * side' of the pipe, bypassing pipes altogether.
386 pproc->sv_stdin[1] = (intptr_t) stdinh;
387 pproc->sv_stdout[1] = (intptr_t) stdouth;
388 pproc->sv_stderr[1] = (intptr_t) stderrh;
390 pproc->last_err = pproc->lerrno = 0;
393 return((HANDLE)pproc);
398 find_file(const char *exec_path, const char *path_var,
399 char *full_fname, DWORD full_len)
406 static const char *extensions[] =
407 /* Should .com come before no-extension case? */
408 { ".exe", ".cmd", ".bat", "", ".com", NULL };
410 fname = xmalloc(strlen(exec_path) + 5);
411 strcpy(fname, exec_path);
412 ext = fname + strlen(fname);
414 for (i = 0; extensions[i]; i++) {
415 strcpy(ext, extensions[i]);
416 if (((req_len = SearchPath (path_var, fname, NULL, full_len,
417 full_fname, NULL)) > 0
418 /* For compatibility with previous code, which
419 used OpenFile, and with Windows operation in
420 general, also look in various default
421 locations, such as Windows directory and
422 Windows System directory. Warning: this also
423 searches PATH in the Make's environment, which
424 might not be what the Makefile wants, but it
425 seems to be OK as a fallback, after the
426 previous SearchPath failed to find on child's
428 || (req_len = SearchPath (NULL, fname, NULL, full_len,
429 full_fname, NULL)) > 0)
430 && req_len <= full_len
432 CreateFile(full_fname,
434 FILE_SHARE_READ | FILE_SHARE_WRITE,
437 FILE_ATTRIBUTE_NORMAL,
438 NULL)) != INVALID_HANDLE_VALUE) {
445 return INVALID_HANDLE_VALUE;
449 * Return non-zero of FNAME specifies a batch file and its name
450 * includes embedded whitespace.
454 batch_file_with_spaces(const char *fname)
456 size_t fnlen = strlen(fname);
459 && (_strnicmp(fname + fnlen - 4, ".bat", 4) == 0
460 || _strnicmp(fname + fnlen - 4, ".cmd", 4) == 0)
461 /* The set of characters in the 2nd arg to strpbrk
462 should be the same one used by make_command_line
463 below to decide whether an argv[] element needs
465 && strpbrk(fname, " \t") != NULL);
470 * Description: Create the child process to be helped
472 * Returns: success <=> 0
474 * Notes/Dependencies:
484 sub_process *pproc = (sub_process *)proc;
485 char *shell_name = 0;
486 int file_not_found=0;
488 char exec_fname[MAX_PATH];
489 const char *path_var = NULL;
492 DWORD bytes_returned;
495 STARTUPINFO startInfo;
496 PROCESS_INFORMATION procInfo;
498 int envsize_needed = 0;
499 int pass_null_exec_path = 0;
502 * Shell script detection... if the exec_path starts with #! then
503 * we want to exec shell-script-name exec-path, not just exec-path
504 * NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl. We do not
505 * hard-code the path to the shell or perl or whatever: Instead, we
506 * assume it's in the path somewhere (generally, the NT tools
510 /* Use the Makefile's value of PATH to look for the program to
511 execute, because it could be different from Make's PATH
512 (e.g., if the target sets its own value. */
514 for (ep = envp; *ep; ep++) {
515 if (strncmp (*ep, "PATH=", 5) == 0
516 || strncmp (*ep, "Path=", 5) == 0) {
521 exec_handle = find_file(exec_path, path_var,
522 exec_fname, sizeof(exec_fname));
525 * If we couldn't open the file, just assume that Windows will be
526 * somehow able to find and execute it. If the first character
527 * of the command is '/', assume they set SHELL to a Unixy shell
528 * that have some magic mounts known only to it, and run the whole
529 * command via $SHELL -c "COMMAND" instead.
531 if (exec_handle == INVALID_HANDLE_VALUE) {
532 if (exec_path[0] == '/') {
537 strcpy(buf, variable_expand ("$(SHELL)"));
538 shell_name = &buf[0];
539 strcpy(exec_fname, "-c");
540 /* Construct a single command string in argv[0]. */
542 arglen += strlen(*argvi) + 1;
545 new_argv0 = xmalloc(arglen + 1);
547 for (argvi = argv; *argvi; argvi++) {
548 strcat(new_argv0, *argvi);
549 strcat(new_argv0, " ");
551 /* Remove the extra blank at the end. */
552 new_argv0[arglen-1] = '\0';
561 /* Attempt to read the first line of the file */
562 if (ReadFile( exec_handle,
563 buf, sizeof(buf) - 1, /* leave room for trailing NULL */
564 &bytes_returned, 0) == FALSE || bytes_returned < 2) {
566 pproc->last_err = GetLastError();
567 pproc->lerrno = E_IO;
568 CloseHandle(exec_handle);
571 if (buf[0] == '#' && buf[1] == '!') {
573 * This is a shell script... Change the command line from
574 * exec_path args to shell_name exec_path args
578 /* Make sure buf is NULL terminated */
579 buf[bytes_returned] = 0;
581 * Depending on the file system type, etc. the first line
582 * of the shell script may end with newline or newline-carriage-return
583 * Whatever it ends with, cut it off.
585 p= strchr(buf, '\n');
588 p = strchr(buf, '\r');
593 * Find base name of shell
595 shell_name = strrchr( buf, '/');
599 shell_name = &buf[2];/* skipping "#!" */
603 CloseHandle(exec_handle);
609 command_line = make_command_line( shell_name, exec_path, argv);
611 /* If exec_fname includes whitespace, CreateProcess
612 behaves erratically and unreliably, and often fails
613 if argv[0] also includes whitespace (and thus will
614 be quoted by make_command_line below). So in that
615 case, we don't pass exec_fname as the 1st arg to
616 CreateProcess, but instead replace argv[0] with
617 exec_fname (to keep its leading directories and
618 extension as found by find_file), and pass NULL to
619 CreateProcess as its 1st arg. This works around
620 the bugs in CreateProcess, which are probably
621 caused by its passing the command to cmd.exe with
622 some incorrect quoting. */
624 && batch_file_with_spaces(exec_fname)
625 && _stricmp(exec_path, argv[0]) == 0) {
629 pass_null_exec_path = 1;
630 /* Rewrite argv[] replacing argv[0] with exec_fname. */
631 for (argvi = argv + 1, arglen = strlen(exec_fname) + 1;
634 arglen += strlen(*argvi) + 1;
636 new_argv = xmalloc(arglen);
637 p = strcpy(new_argv, exec_fname) + strlen(exec_fname) + 1;
638 for (argvi = argv + 1, i = 1; *argvi; argvi++, i++) {
641 p += strlen(*argvi) + 1;
647 command_line = make_command_line( shell_name, exec_fname, argv);
650 if ( command_line == NULL ) {
652 pproc->lerrno = E_NO_MEM;
657 if (arr2envblk(envp, &envblk, &envsize_needed) == FALSE) {
658 pproc->lerrno = E_NO_MEM;
659 free( command_line );
660 if ((pproc->last_err == ERROR_INVALID_PARAMETER
661 || pproc->last_err == ERROR_MORE_DATA)
662 && envsize_needed > 32*1024) {
663 fprintf (stderr, "CreateProcess failed, probably because environment is too large (%d bytes).\n",
671 if (shell_name || file_not_found || pass_null_exec_path) {
672 exec_path = 0; /* Search for the program in %Path% */
674 exec_path = exec_fname;
678 * Set up inherited stdin, stdout, stderr for child
680 memset(&startInfo, '\0', sizeof(startInfo));
681 GetStartupInfo(&startInfo);
682 startInfo.dwFlags = STARTF_USESTDHANDLES;
683 startInfo.lpReserved = 0;
684 startInfo.cbReserved2 = 0;
685 startInfo.lpReserved2 = 0;
686 startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
687 startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
688 startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];
694 DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n",
695 exec_path ? exec_path : "NULL",
696 command_line ? command_line : "NULL"));
701 0, /* default security attributes for thread */
702 TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
705 0, /* default starting directory */
707 &procInfo) == FALSE) {
709 pproc->last_err = GetLastError();
710 pproc->lerrno = E_FORK;
711 fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
712 exec_path ? exec_path : "NULL", command_line);
714 free( command_line );
719 pproc->pid = (pid_t)procInfo.hProcess;
720 /* Close the thread handle -- we'll just watch the process */
721 CloseHandle(procInfo.hThread);
723 /* Close the halves of the pipes we don't need */
724 if ((HANDLE)pproc->sv_stdin[1] != INVALID_HANDLE_VALUE)
725 CloseHandle((HANDLE)pproc->sv_stdin[1]);
726 if ((HANDLE)pproc->sv_stdout[1] != INVALID_HANDLE_VALUE)
727 CloseHandle((HANDLE)pproc->sv_stdout[1]);
728 if ((HANDLE)pproc->sv_stderr[1] != INVALID_HANDLE_VALUE)
729 CloseHandle((HANDLE)pproc->sv_stderr[1]);
730 pproc->sv_stdin[1] = 0;
731 pproc->sv_stdout[1] = 0;
732 pproc->sv_stderr[1] = 0;
734 free( command_line );
744 proc_stdin_thread(sub_process *pproc)
748 if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt,
749 &in_done, NULL) == FALSE)
751 // This if should never be true for anonymous pipes, but gives
752 // us a chance to change I/O mechanisms later
753 if (in_done < pproc->incnt) {
754 pproc->incnt -= in_done;
755 pproc->inp += in_done;
760 return 0; // for compiler warnings only.. not reached
764 proc_stdout_thread(sub_process *pproc)
766 DWORD bufsize = 1024;
769 pproc->outp = malloc(bufsize);
770 if (pproc->outp == NULL)
775 if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL)
777 /* map_windows32_error_to_string(GetLastError());*/
782 if (pproc->outcnt + nread > bufsize) {
783 bufsize += nread + 512;
784 pproc->outp = realloc(pproc->outp, bufsize);
785 if (pproc->outp == NULL) {
790 pproc->outp[pproc->outcnt++] = c;
796 proc_stderr_thread(sub_process *pproc)
798 DWORD bufsize = 1024;
801 pproc->errp = malloc(bufsize);
802 if (pproc->errp == NULL)
807 if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) {
808 map_windows32_error_to_string(GetLastError());
813 if (pproc->errcnt + nread > bufsize) {
814 bufsize += nread + 512;
815 pproc->errp = realloc(pproc->errp, bufsize);
816 if (pproc->errp == NULL) {
821 pproc->errp[pproc->errcnt++] = c;
828 * Purpose: collects output from child process and returns results
834 * Notes/Dependencies:
842 sub_process *pproc = (sub_process *)proc;
843 bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE;
844 HANDLE childhand = (HANDLE) pproc->pid;
845 HANDLE tStdin = NULL, tStdout = NULL, tStderr = NULL;
846 unsigned int dwStdin, dwStdout, dwStderr;
851 bool_t child_dead = FALSE;
852 BOOL GetExitCodeResult;
855 * Create stdin thread, if needed
857 pproc->inp = stdin_data;
858 pproc->incnt = stdin_data_len;
861 CloseHandle((HANDLE)pproc->sv_stdin[0]);
862 pproc->sv_stdin[0] = 0;
864 tStdin = (HANDLE) _beginthreadex( 0, 1024,
865 (unsigned (__stdcall *) (void *))proc_stdin_thread,
868 pproc->last_err = GetLastError();
869 pproc->lerrno = E_SCALL;
875 * Assume child will produce stdout and stderr
877 tStdout = (HANDLE) _beginthreadex( 0, 1024,
878 (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0,
880 tStderr = (HANDLE) _beginthreadex( 0, 1024,
881 (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,
884 if (tStdout == 0 || tStderr == 0) {
886 pproc->last_err = GetLastError();
887 pproc->lerrno = E_SCALL;
893 * Wait for all I/O to finish and for the child process to exit
896 while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {
899 wait_list[wait_count++] = tStdin;
902 wait_list[wait_count++] = tStdout;
905 wait_list[wait_count++] = tStderr;
908 wait_list[wait_count++] = childhand;
911 wait_return = WaitForMultipleObjects(wait_count, wait_list,
912 FALSE, /* don't wait for all: one ready will do */
913 child_dead? 1000 :INFINITE); /* after the child dies, subthreads have
914 one second to collect all remaining output */
916 if (wait_return == WAIT_FAILED) {
917 /* map_windows32_error_to_string(GetLastError());*/
918 pproc->last_err = GetLastError();
919 pproc->lerrno = E_SCALL;
923 ready_hand = wait_list[wait_return - WAIT_OBJECT_0];
925 if (ready_hand == tStdin) {
926 CloseHandle((HANDLE)pproc->sv_stdin[0]);
927 pproc->sv_stdin[0] = 0;
932 } else if (ready_hand == tStdout) {
934 CloseHandle((HANDLE)pproc->sv_stdout[0]);
935 pproc->sv_stdout[0] = 0;
936 CloseHandle(tStdout);
940 } else if (ready_hand == tStderr) {
942 CloseHandle((HANDLE)pproc->sv_stderr[0]);
943 pproc->sv_stderr[0] = 0;
944 CloseHandle(tStderr);
948 } else if (ready_hand == childhand) {
951 GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
952 if (ierr == CONTROL_C_EXIT) {
953 pproc->signal = SIGINT;
955 pproc->exit_code = ierr;
957 if (GetExitCodeResult == FALSE) {
958 pproc->last_err = GetLastError();
959 pproc->lerrno = E_SCALL;
966 /* ?? Got back a handle we didn't query ?? */
968 pproc->lerrno = E_FAIL;
977 CloseHandle(tStdout);
979 CloseHandle(tStderr);
990 * Purpose: collects output from child process and returns results
996 * Notes/Dependencies:
1005 BOOL GetExitCodeResult;
1009 pproc = process_wait_for_any_private(1, 0);
1011 pproc = (sub_process *)proc;
1013 /* some sort of internal error */
1017 childhand = (HANDLE) pproc->pid;
1020 * This function is poorly named, and could also be used just to wait
1021 * for child death if you're doing your own pipe I/O. If that is
1022 * the case, close the pipe handles here.
1024 if (pproc->sv_stdin[0]) {
1025 CloseHandle((HANDLE)pproc->sv_stdin[0]);
1026 pproc->sv_stdin[0] = 0;
1028 if (pproc->sv_stdout[0]) {
1029 CloseHandle((HANDLE)pproc->sv_stdout[0]);
1030 pproc->sv_stdout[0] = 0;
1032 if (pproc->sv_stderr[0]) {
1033 CloseHandle((HANDLE)pproc->sv_stderr[0]);
1034 pproc->sv_stderr[0] = 0;
1038 * Wait for the child process to exit
1041 wait_return = WaitForSingleObject(childhand, INFINITE);
1043 if (wait_return != WAIT_OBJECT_0) {
1044 /* map_windows32_error_to_string(GetLastError());*/
1045 pproc->last_err = GetLastError();
1046 pproc->lerrno = E_SCALL;
1050 GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
1051 if (ierr == CONTROL_C_EXIT) {
1052 pproc->signal = SIGINT;
1054 pproc->exit_code = ierr;
1056 if (GetExitCodeResult == FALSE) {
1057 pproc->last_err = GetLastError();
1058 pproc->lerrno = E_SCALL;
1070 * Description: Clean up any leftover handles, etc. It is up to the
1071 * caller to manage and free the input, output, and stderr buffers.
1077 sub_process *pproc = (sub_process *)proc;
1080 if (pproc->using_pipes) {
1081 for (i= 0; i <= 1; i++) {
1082 if ((HANDLE)pproc->sv_stdin[i]
1083 && (HANDLE)pproc->sv_stdin[i] != INVALID_HANDLE_VALUE)
1084 CloseHandle((HANDLE)pproc->sv_stdin[i]);
1085 if ((HANDLE)pproc->sv_stdout[i]
1086 && (HANDLE)pproc->sv_stdout[i] != INVALID_HANDLE_VALUE)
1087 CloseHandle((HANDLE)pproc->sv_stdout[i]);
1088 if ((HANDLE)pproc->sv_stderr[i]
1089 && (HANDLE)pproc->sv_stderr[i] != INVALID_HANDLE_VALUE)
1090 CloseHandle((HANDLE)pproc->sv_stderr[i]);
1093 if ((HANDLE)pproc->pid)
1094 CloseHandle((HANDLE)pproc->pid);
1102 * Create a command line buffer to pass to CreateProcess
1104 * Returns: the buffer or NULL for failure
1105 * Shell case: sh_name a:/full/path/to/script argv[1] argv[2] ...
1106 * Otherwise: argv[0] argv[1] argv[2] ...
1108 * Notes/Dependencies:
1109 * CreateProcess does not take an argv, so this command creates a
1110 * command line for the executable.
1114 make_command_line( char *shell_name, char *full_exec_path, char **argv)
1118 int* enclose_in_quotes = NULL;
1119 int* enclose_in_quotes_i;
1120 unsigned int bytes_required = 0;
1122 char* command_line_i;
1123 int cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */
1124 int have_sh = 0; /* HAVE_CYGWIN_SHELL */
1126 #ifdef HAVE_CYGWIN_SHELL
1127 have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe"));
1131 if (shell_name && full_exec_path) {
1133 = strlen(shell_name) + 1 + strlen(full_exec_path);
1135 * Skip argv[0] if any, when shell_name is given.
1136 * The special case of "-c" in full_exec_path means
1137 * argv[0] is not the shell name, but the command string
1138 * to pass to the shell.
1140 if (*argv && strcmp(full_exec_path, "-c")) argv++;
1142 * Add one for the intervening space.
1144 if (*argv) bytes_required++;
1148 while (*(argvi++)) argc++;
1151 enclose_in_quotes = (int*) calloc(1, argc * sizeof(int));
1153 if (!enclose_in_quotes) {
1158 /* We have to make one pass through each argv[i] to see if we need
1159 * to enclose it in ", so we might as well figure out how much
1160 * memory we'll need on the same pass.
1164 enclose_in_quotes_i = enclose_in_quotes;
1167 unsigned int backslash_count = 0;
1170 * We have to enclose empty arguments in ".
1172 if (!(*p)) *enclose_in_quotes_i = 1;
1178 * We have to insert a backslash for each "
1179 * and each \ that precedes the ".
1181 bytes_required += (backslash_count + 1);
1182 backslash_count = 0;
1185 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1191 * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
1192 * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
1193 * that argv in always equals argv out. This was removed. Say you have
1194 * such a program named glob.exe. You enter
1196 * at the sh command prompt. Obviously the intent is to make glob do the
1197 * wildcarding instead of sh. If we set *enclose_in_quotes_i for '*' or '?',
1198 * then the command line that glob would see would be
1200 * and the _setargv in SETARGV.OBJ would _not_ expand the *.
1204 *enclose_in_quotes_i = 1;
1208 backslash_count = 0;
1213 * Add one for each character in argv[i].
1220 if (*enclose_in_quotes_i) {
1222 * Add one for each enclosing ",
1223 * and one for each \ that precedes the
1226 bytes_required += (backslash_count + 2);
1230 * Add one for the intervening space.
1232 if (*(++argvi)) bytes_required++;
1233 enclose_in_quotes_i++;
1237 * Add one for the terminating NULL.
1241 command_line = (char*) malloc(bytes_required);
1243 if (!command_line) {
1244 free(enclose_in_quotes);
1248 command_line_i = command_line;
1250 if (shell_name && full_exec_path) {
1251 while(*shell_name) {
1252 *(command_line_i++) = *(shell_name++);
1255 *(command_line_i++) = ' ';
1257 while(*full_exec_path) {
1258 *(command_line_i++) = *(full_exec_path++);
1262 *(command_line_i++) = ' ';
1267 enclose_in_quotes_i = enclose_in_quotes;
1271 unsigned int backslash_count = 0;
1273 if (*enclose_in_quotes_i) {
1274 *(command_line_i++) = '\"';
1279 if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */
1280 /* instead of a \", cygwin likes "" */
1281 *(command_line_i++) = '\"';
1285 * We have to insert a backslash for the "
1286 * and each \ that precedes the ".
1290 while(backslash_count) {
1291 *(command_line_i++) = '\\';
1295 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1296 } else if (*p == '\\') {
1299 backslash_count = 0;
1304 * Copy the character.
1306 *(command_line_i++) = *(p++);
1309 if (*enclose_in_quotes_i) {
1310 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1312 * Add one \ for each \ that precedes the
1315 while(backslash_count--) {
1316 *(command_line_i++) = '\\';
1319 *(command_line_i++) = '\"';
1323 * Append an intervening space.
1326 *(command_line_i++) = ' ';
1329 enclose_in_quotes_i++;
1333 * Append the terminating NULL.
1335 *command_line_i = '\0';
1337 free(enclose_in_quotes);
1338 return command_line;
1342 * Description: Given an argv and optional envp, launch the process
1343 * using the default stdin, stdout, and stderr handles.
1344 * Also, register process so that process_wait_for_any_private()
1345 * can be used via process_file_io(NULL) or
1346 * process_wait_for_any().
1350 * Notes/Dependencies:
1359 HANDLE hIn = INVALID_HANDLE_VALUE;
1360 HANDLE hOut = INVALID_HANDLE_VALUE;
1361 HANDLE hErr = INVALID_HANDLE_VALUE;
1362 HANDLE hProcess, tmpIn, tmpOut, tmpErr;
1365 if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
1366 DB (DB_JOBS, ("process_easy: All process slots used up\n"));
1367 return INVALID_HANDLE_VALUE;
1369 /* Standard handles returned by GetStdHandle can be NULL or
1370 INVALID_HANDLE_VALUE if the parent process closed them. If that
1371 happens, we open the null device and pass its handle to
1372 CreateProcess as the corresponding handle to inherit. */
1373 tmpIn = GetStdHandle(STD_INPUT_HANDLE);
1374 if (DuplicateHandle(GetCurrentProcess(),
1376 GetCurrentProcess(),
1380 DUPLICATE_SAME_ACCESS) == FALSE) {
1381 if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
1382 tmpIn = CreateFile("NUL", GENERIC_READ,
1383 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1384 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1385 if (tmpIn != INVALID_HANDLE_VALUE
1386 && DuplicateHandle(GetCurrentProcess(),
1388 GetCurrentProcess(),
1392 DUPLICATE_SAME_ACCESS) == FALSE)
1395 if (hIn == INVALID_HANDLE_VALUE) {
1396 fprintf(stderr, "process_easy: DuplicateHandle(In) failed (e=%ld)\n", e);
1397 return INVALID_HANDLE_VALUE;
1401 tmpOut = (HANDLE)_get_osfhandle (outfd);
1403 tmpOut = GetStdHandle (STD_OUTPUT_HANDLE);
1404 if (DuplicateHandle(GetCurrentProcess(),
1406 GetCurrentProcess(),
1410 DUPLICATE_SAME_ACCESS) == FALSE) {
1411 if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
1412 tmpOut = CreateFile("NUL", GENERIC_WRITE,
1413 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1414 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1415 if (tmpOut != INVALID_HANDLE_VALUE
1416 && DuplicateHandle(GetCurrentProcess(),
1418 GetCurrentProcess(),
1422 DUPLICATE_SAME_ACCESS) == FALSE)
1423 CloseHandle(tmpOut);
1425 if (hOut == INVALID_HANDLE_VALUE) {
1426 fprintf(stderr, "process_easy: DuplicateHandle(Out) failed (e=%ld)\n", e);
1427 return INVALID_HANDLE_VALUE;
1431 tmpErr = (HANDLE)_get_osfhandle (errfd);
1433 tmpErr = GetStdHandle(STD_ERROR_HANDLE);
1434 if (DuplicateHandle(GetCurrentProcess(),
1436 GetCurrentProcess(),
1440 DUPLICATE_SAME_ACCESS) == FALSE) {
1441 if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
1442 tmpErr = CreateFile("NUL", GENERIC_WRITE,
1443 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1444 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1445 if (tmpErr != INVALID_HANDLE_VALUE
1446 && DuplicateHandle(GetCurrentProcess(),
1448 GetCurrentProcess(),
1452 DUPLICATE_SAME_ACCESS) == FALSE)
1453 CloseHandle(tmpErr);
1455 if (hErr == INVALID_HANDLE_VALUE) {
1456 fprintf(stderr, "process_easy: DuplicateHandle(Err) failed (e=%ld)\n", e);
1457 return INVALID_HANDLE_VALUE;
1461 hProcess = process_init_fd(hIn, hOut, hErr);
1463 if (process_begin(hProcess, argv, envp, argv[0], NULL)) {
1464 fake_exits_pending++;
1465 /* process_begin() failed: make a note of that. */
1466 if (!((sub_process*) hProcess)->last_err)
1467 ((sub_process*) hProcess)->last_err = -1;
1468 ((sub_process*) hProcess)->exit_code = process_last_err(hProcess);
1470 /* close up unused handles */
1471 if (hIn != INVALID_HANDLE_VALUE)
1473 if (hOut != INVALID_HANDLE_VALUE)
1475 if (hErr != INVALID_HANDLE_VALUE)
1479 process_register(hProcess);