1 /* Process handling for Windows.
2 Copyright (C) 1996-2013 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 */
37 static char *make_command_line(char *shell_name, char *exec_path, char **argv);
39 typedef struct sub_process_t {
41 intptr_t sv_stdout[2];
42 intptr_t sv_stderr[2];
47 volatile DWORD outcnt;
49 volatile DWORD errcnt;
57 /* keep track of children so we can implement a waitpid-like routine */
58 static sub_process *proc_array[MAXIMUM_WAIT_OBJECTS];
59 static int proc_index = 0;
60 static int fake_exits_pending = 0;
62 /* Windows jobserver implementation variables */
63 static char jobserver_semaphore_name[MAX_PATH + 1];
64 static HANDLE jobserver_semaphore = NULL;
66 /* Open existing jobserver semaphore */
67 int open_jobserver_semaphore(const char* name)
69 jobserver_semaphore = OpenSemaphore(
70 SEMAPHORE_ALL_ACCESS, // Semaphore access setting
71 FALSE, // Child processes DON'T inherit
72 name); // Semaphore name
74 if (jobserver_semaphore == NULL)
80 /* Create new jobserver semaphore */
81 int create_jobserver_semaphore(int tokens)
83 sprintf(jobserver_semaphore_name, "gmake_semaphore_%d", _getpid());
85 jobserver_semaphore = CreateSemaphore(
86 NULL, // Use default security descriptor
87 tokens, // Initial count
88 tokens, // Maximum count
89 jobserver_semaphore_name); // Semaphore name
91 if (jobserver_semaphore == NULL)
97 /* Close jobserver semaphore */
98 void free_jobserver_semaphore()
100 if (jobserver_semaphore != NULL)
102 CloseHandle(jobserver_semaphore);
103 jobserver_semaphore = NULL;
107 /* Decrement semaphore count */
108 int acquire_jobserver_semaphore()
110 DWORD dwEvent = WaitForSingleObject(
111 jobserver_semaphore, // Handle to semaphore
112 0); // DON'T wait on semaphore
114 return (dwEvent == WAIT_OBJECT_0);
117 /* Increment semaphore count */
118 int release_jobserver_semaphore()
120 BOOL bResult = ReleaseSemaphore(
121 jobserver_semaphore, // handle to semaphore
122 1, // increase count by one
123 NULL); // not interested in previous count
128 int has_jobserver_semaphore()
130 return (jobserver_semaphore != NULL);
133 char* get_jobserver_semaphore_name()
135 return (jobserver_semaphore_name);
138 /* Wait for either the jobserver semaphore to become signalled or one of our
139 * child processes to terminate.
141 int wait_for_semaphore_or_child_process()
143 HANDLE handles[MAXIMUM_WAIT_OBJECTS];
144 DWORD dwHandleCount = 1;
148 /* Add jobserver semaphore to first slot. */
149 handles[0] = jobserver_semaphore;
151 /* Build array of handles to wait for */
152 for (i = 0; i < proc_index; i++)
154 /* Don't wait on child processes that have already finished */
155 if (fake_exits_pending && proc_array[i]->exit_code)
158 handles[dwHandleCount++] = (HANDLE) proc_array[i]->pid;
161 dwEvent = WaitForMultipleObjects(
162 dwHandleCount, // number of objects in array
163 handles, // array of objects
164 FALSE, // wait for any object
165 INFINITE); // wait until object is signalled
173 /* Indicate that the semaphore was signalled */
177 /* Assume that one or more of the child processes terminated. */
183 * When a process has been waited for, adjust the wait state
184 * array so that we don't wait for it again
187 process_adjust_wait_state(sub_process* pproc)
194 for (i = 0; i < proc_index; i++)
195 if (proc_array[i]->pid == pproc->pid)
198 if (i < proc_index) {
201 memmove(&proc_array[i], &proc_array[i+1],
202 (proc_index-i) * sizeof(sub_process*));
203 proc_array[proc_index] = NULL;
208 * Waits for any of the registered child processes to finish.
211 process_wait_for_any_private(int block, DWORD* pdwWaitStatus)
213 HANDLE handles[MAXIMUM_WAIT_OBJECTS];
220 /* build array of handles to wait for */
221 for (i = 0; i < proc_index; i++) {
222 handles[i] = (HANDLE) proc_array[i]->pid;
224 if (fake_exits_pending && proc_array[i]->exit_code)
228 /* wait for someone to exit */
229 if (!fake_exits_pending) {
230 retval = WaitForMultipleObjects(proc_index, handles, FALSE, (block ? INFINITE : 0));
231 which = retval - WAIT_OBJECT_0;
233 fake_exits_pending--;
234 retval = !WAIT_FAILED;
238 /* If the pointer is not NULL, set the wait status result variable. */
240 *pdwWaitStatus = retval;
242 /* return pointer to process */
243 if ((retval == WAIT_TIMEOUT) || (retval == WAIT_FAILED)) {
247 sub_process* pproc = proc_array[which];
248 process_adjust_wait_state(pproc);
254 * Terminate a process.
257 process_kill(HANDLE proc, int signal)
259 sub_process* pproc = (sub_process*) proc;
260 pproc->signal = signal;
261 return (TerminateProcess((HANDLE) pproc->pid, signal));
265 * Use this function to register processes you wish to wait for by
266 * calling process_file_io(NULL) or process_wait_any(). This must be done
267 * because it is possible for callers of this library to reuse the same
268 * handle for multiple processes launches :-(
271 process_register(HANDLE proc)
273 if (proc_index < MAXIMUM_WAIT_OBJECTS)
274 proc_array[proc_index++] = (sub_process *) proc;
278 * Return the number of processes that we are still waiting for.
281 process_used_slots(void)
287 * Public function which works kind of like waitpid(). Wait for any
288 * of the children to die and return results. To call this function,
289 * you must do 1 of things:
291 * x = process_easy(...);
295 * x = process_init_fd();
296 * process_register(x);
300 * x = process_init();
301 * process_register(x);
303 * You must NOT then call process_pipe_io() because this function is
304 * not capable of handling automatic notification of any child
309 process_wait_for_any(int block, DWORD* pdwWaitStatus)
311 sub_process* pproc = process_wait_for_any_private(block, pdwWaitStatus);
317 * Ouch! can't tell caller if this fails directly. Caller
318 * will have to use process_last_err()
320 (void) process_file_io(pproc);
321 return ((HANDLE) pproc);
326 process_signal(HANDLE proc)
328 if (proc == INVALID_HANDLE_VALUE) return 0;
329 return (((sub_process *)proc)->signal);
333 process_last_err(HANDLE proc)
335 if (proc == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
336 return (((sub_process *)proc)->last_err);
340 process_exit_code(HANDLE proc)
342 if (proc == INVALID_HANDLE_VALUE) return EXIT_FAILURE;
343 return (((sub_process *)proc)->exit_code);
347 process_noinherit(int fd)
349 HANDLE fh = (HANDLE)_get_osfhandle(fd);
351 if (fh && fh != INVALID_HANDLE_VALUE)
352 SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0);
357 All the following functions are currently unused.
358 All of them would crash gmake if called with argument INVALID_HANDLE_VALUE.
359 Hence whoever wants to use one of this functions must invent and implement
360 a reasonable error handling for this function.
363 process_outbuf(HANDLE proc)
365 return (((sub_process *)proc)->outp);
369 process_errbuf(HANDLE proc)
371 return (((sub_process *)proc)->errp);
375 process_outcnt(HANDLE proc)
377 return (((sub_process *)proc)->outcnt);
381 process_errcnt(HANDLE proc)
383 return (((sub_process *)proc)->errcnt);
387 process_pipes(HANDLE proc, int pipes[3])
389 pipes[0] = ((sub_process *)proc)->sv_stdin[0];
390 pipes[1] = ((sub_process *)proc)->sv_stdout[0];
391 pipes[2] = ((sub_process *)proc)->sv_stderr[0];
401 * open file descriptors for attaching stdin/stdout/sterr
403 HANDLE stdin_pipes[2];
404 HANDLE stdout_pipes[2];
405 HANDLE stderr_pipes[2];
406 SECURITY_ATTRIBUTES inherit;
407 BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
409 pproc = malloc(sizeof(*pproc));
410 memset(pproc, 0, sizeof(*pproc));
412 /* We can't use NULL for lpSecurityDescriptor because that
413 uses the default security descriptor of the calling process.
414 Instead we use a security descriptor with no DACL. This
415 allows nonrestricted access to the associated objects. */
417 if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd),
418 SECURITY_DESCRIPTOR_REVISION)) {
419 pproc->last_err = GetLastError();
420 pproc->lerrno = E_SCALL;
421 return((HANDLE)pproc);
424 inherit.nLength = sizeof(inherit);
425 inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd);
426 inherit.bInheritHandle = TRUE;
428 // By convention, parent gets pipe[0], and child gets pipe[1]
429 // This means the READ side of stdin pipe goes into pipe[1]
430 // and the WRITE side of the stdout and stderr pipes go into pipe[1]
431 if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE ||
432 CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE ||
433 CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) {
435 pproc->last_err = GetLastError();
436 pproc->lerrno = E_SCALL;
437 return((HANDLE)pproc);
441 // Mark the parent sides of the pipes as non-inheritable
443 if (SetHandleInformation(stdin_pipes[0],
444 HANDLE_FLAG_INHERIT, 0) == FALSE ||
445 SetHandleInformation(stdout_pipes[0],
446 HANDLE_FLAG_INHERIT, 0) == FALSE ||
447 SetHandleInformation(stderr_pipes[0],
448 HANDLE_FLAG_INHERIT, 0) == FALSE) {
450 pproc->last_err = GetLastError();
451 pproc->lerrno = E_SCALL;
452 return((HANDLE)pproc);
454 pproc->sv_stdin[0] = (intptr_t) stdin_pipes[0];
455 pproc->sv_stdin[1] = (intptr_t) stdin_pipes[1];
456 pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0];
457 pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1];
458 pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0];
459 pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1];
461 pproc->using_pipes = 1;
465 return((HANDLE)pproc);
470 process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
474 pproc = malloc(sizeof(*pproc));
476 memset(pproc, 0, sizeof(*pproc));
479 * Just pass the provided file handles to the 'child
480 * side' of the pipe, bypassing pipes altogether.
482 pproc->sv_stdin[1] = (intptr_t) stdinh;
483 pproc->sv_stdout[1] = (intptr_t) stdouth;
484 pproc->sv_stderr[1] = (intptr_t) stderrh;
486 pproc->last_err = pproc->lerrno = 0;
489 return((HANDLE)pproc);
494 find_file(const char *exec_path, const char *path_var,
495 char *full_fname, DWORD full_len)
502 static const char *extensions[] =
503 /* Should .com come before no-extension case? */
504 { ".exe", ".cmd", ".bat", "", ".com", NULL };
506 fname = xmalloc(strlen(exec_path) + 5);
507 strcpy(fname, exec_path);
508 ext = fname + strlen(fname);
510 for (i = 0; extensions[i]; i++) {
511 strcpy(ext, extensions[i]);
512 if (((req_len = SearchPath (path_var, fname, NULL, full_len,
513 full_fname, NULL)) > 0
514 /* For compatibility with previous code, which
515 used OpenFile, and with Windows operation in
516 general, also look in various default
517 locations, such as Windows directory and
518 Windows System directory. Warning: this also
519 searches PATH in the Make's environment, which
520 might not be what the Makefile wants, but it
521 seems to be OK as a fallback, after the
522 previous SearchPath failed to find on child's
524 || (req_len = SearchPath (NULL, fname, NULL, full_len,
525 full_fname, NULL)) > 0)
526 && req_len <= full_len
528 CreateFile(full_fname,
530 FILE_SHARE_READ | FILE_SHARE_WRITE,
533 FILE_ATTRIBUTE_NORMAL,
534 NULL)) != INVALID_HANDLE_VALUE) {
541 return INVALID_HANDLE_VALUE;
545 * Return non-zero of FNAME specifies a batch file and its name
546 * includes embedded whitespace.
550 batch_file_with_spaces(const char *fname)
552 size_t fnlen = strlen(fname);
555 && (_strnicmp(fname + fnlen - 4, ".bat", 4) == 0
556 || _strnicmp(fname + fnlen - 4, ".cmd", 4) == 0)
557 /* The set of characters in the 2nd arg to strpbrk
558 should be the same one used by make_command_line
559 below to decide whether an argv[] element needs
561 && strpbrk(fname, " \t") != NULL);
566 * Description: Create the child process to be helped
568 * Returns: success <=> 0
570 * Notes/Dependencies:
580 sub_process *pproc = (sub_process *)proc;
581 char *shell_name = 0;
582 int file_not_found=0;
584 char exec_fname[MAX_PATH];
585 const char *path_var = NULL;
588 DWORD bytes_returned;
591 STARTUPINFO startInfo;
592 PROCESS_INFORMATION procInfo;
594 int pass_null_exec_path = 0;
597 * Shell script detection... if the exec_path starts with #! then
598 * we want to exec shell-script-name exec-path, not just exec-path
599 * NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl. We do not
600 * hard-code the path to the shell or perl or whatever: Instead, we
601 * assume it's in the path somewhere (generally, the NT tools
605 /* Use the Makefile's value of PATH to look for the program to
606 execute, because it could be different from Make's PATH
607 (e.g., if the target sets its own value. */
609 for (ep = envp; *ep; ep++) {
610 if (strncmp (*ep, "PATH=", 5) == 0
611 || strncmp (*ep, "Path=", 5) == 0) {
616 exec_handle = find_file(exec_path, path_var,
617 exec_fname, sizeof(exec_fname));
620 * If we couldn't open the file, just assume that Windows will be
621 * somehow able to find and execute it.
623 if (exec_handle == INVALID_HANDLE_VALUE) {
627 /* Attempt to read the first line of the file */
628 if (ReadFile( exec_handle,
629 buf, sizeof(buf) - 1, /* leave room for trailing NULL */
630 &bytes_returned, 0) == FALSE || bytes_returned < 2) {
632 pproc->last_err = GetLastError();
633 pproc->lerrno = E_IO;
634 CloseHandle(exec_handle);
637 if (buf[0] == '#' && buf[1] == '!') {
639 * This is a shell script... Change the command line from
640 * exec_path args to shell_name exec_path args
644 /* Make sure buf is NULL terminated */
645 buf[bytes_returned] = 0;
647 * Depending on the file system type, etc. the first line
648 * of the shell script may end with newline or newline-carriage-return
649 * Whatever it ends with, cut it off.
651 p= strchr(buf, '\n');
654 p = strchr(buf, '\r');
659 * Find base name of shell
661 shell_name = strrchr( buf, '/');
665 shell_name = &buf[2];/* skipping "#!" */
669 CloseHandle(exec_handle);
675 command_line = make_command_line( shell_name, exec_path, argv);
677 /* If exec_fname includes whitespace, CreateProcess
678 behaves erratically and unreliably, and often fails
679 if argv[0] also includes whitespace (and thus will
680 be quoted by make_command_line below). So in that
681 case, we don't pass exec_fname as the 1st arg to
682 CreateProcess, but instead replace argv[0] with
683 exec_fname (to keep its leading directories and
684 extension as found by find_file), and pass NULL to
685 CreateProcess as its 1st arg. This works around
686 the bugs in CreateProcess, which are probably
687 caused by its passing the command to cmd.exe with
688 some incorrect quoting. */
690 && batch_file_with_spaces(exec_fname)
691 && _stricmp(exec_path, argv[0]) == 0) {
692 pass_null_exec_path = 1;
694 argv[0] = xstrdup(exec_fname);
696 command_line = make_command_line( shell_name, exec_fname, argv);
699 if ( command_line == NULL ) {
701 pproc->lerrno = E_NO_MEM;
706 if (arr2envblk(envp, &envblk) ==FALSE) {
708 pproc->lerrno = E_NO_MEM;
709 free( command_line );
714 if (shell_name || file_not_found || pass_null_exec_path) {
715 exec_path = 0; /* Search for the program in %Path% */
717 exec_path = exec_fname;
721 * Set up inherited stdin, stdout, stderr for child
723 GetStartupInfo(&startInfo);
724 startInfo.dwFlags = STARTF_USESTDHANDLES;
725 startInfo.lpReserved = 0;
726 startInfo.cbReserved2 = 0;
727 startInfo.lpReserved2 = 0;
728 startInfo.lpTitle = shell_name ? shell_name : exec_path;
729 startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
730 startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
731 startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];
734 if (envblk) free(envblk);
737 DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n",
738 exec_path ? exec_path : "NULL",
739 command_line ? command_line : "NULL"));
744 0, /* default security attributes for thread */
745 TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
748 0, /* default starting directory */
750 &procInfo) == FALSE) {
752 pproc->last_err = GetLastError();
753 pproc->lerrno = E_FORK;
754 fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
755 exec_path ? exec_path : "NULL", command_line);
756 if (envblk) free(envblk);
757 free( command_line );
762 pproc->pid = (pid_t)procInfo.hProcess;
763 /* Close the thread handle -- we'll just watch the process */
764 CloseHandle(procInfo.hThread);
766 /* Close the halves of the pipes we don't need */
767 if ((HANDLE)pproc->sv_stdin[1] != INVALID_HANDLE_VALUE)
768 CloseHandle((HANDLE)pproc->sv_stdin[1]);
769 if ((HANDLE)pproc->sv_stdout[1] != INVALID_HANDLE_VALUE)
770 CloseHandle((HANDLE)pproc->sv_stdout[1]);
771 if ((HANDLE)pproc->sv_stderr[1] != INVALID_HANDLE_VALUE)
772 CloseHandle((HANDLE)pproc->sv_stderr[1]);
773 pproc->sv_stdin[1] = 0;
774 pproc->sv_stdout[1] = 0;
775 pproc->sv_stderr[1] = 0;
777 free( command_line );
778 if (envblk) free(envblk);
787 proc_stdin_thread(sub_process *pproc)
791 if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt,
792 &in_done, NULL) == FALSE)
794 // This if should never be true for anonymous pipes, but gives
795 // us a chance to change I/O mechanisms later
796 if (in_done < pproc->incnt) {
797 pproc->incnt -= in_done;
798 pproc->inp += in_done;
803 return 0; // for compiler warnings only.. not reached
807 proc_stdout_thread(sub_process *pproc)
809 DWORD bufsize = 1024;
812 pproc->outp = malloc(bufsize);
813 if (pproc->outp == NULL)
818 if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL)
820 /* map_windows32_error_to_string(GetLastError());*/
825 if (pproc->outcnt + nread > bufsize) {
826 bufsize += nread + 512;
827 pproc->outp = realloc(pproc->outp, bufsize);
828 if (pproc->outp == NULL) {
833 pproc->outp[pproc->outcnt++] = c;
839 proc_stderr_thread(sub_process *pproc)
841 DWORD bufsize = 1024;
844 pproc->errp = malloc(bufsize);
845 if (pproc->errp == NULL)
850 if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) {
851 map_windows32_error_to_string(GetLastError());
856 if (pproc->errcnt + nread > bufsize) {
857 bufsize += nread + 512;
858 pproc->errp = realloc(pproc->errp, bufsize);
859 if (pproc->errp == NULL) {
864 pproc->errp[pproc->errcnt++] = c;
871 * Purpose: collects output from child process and returns results
877 * Notes/Dependencies:
885 sub_process *pproc = (sub_process *)proc;
886 bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE;
887 HANDLE childhand = (HANDLE) pproc->pid;
888 HANDLE tStdin = NULL, tStdout = NULL, tStderr = NULL;
889 unsigned int dwStdin, dwStdout, dwStderr;
894 bool_t child_dead = FALSE;
895 BOOL GetExitCodeResult;
898 * Create stdin thread, if needed
900 pproc->inp = stdin_data;
901 pproc->incnt = stdin_data_len;
904 CloseHandle((HANDLE)pproc->sv_stdin[0]);
905 pproc->sv_stdin[0] = 0;
907 tStdin = (HANDLE) _beginthreadex( 0, 1024,
908 (unsigned (__stdcall *) (void *))proc_stdin_thread,
911 pproc->last_err = GetLastError();
912 pproc->lerrno = E_SCALL;
918 * Assume child will produce stdout and stderr
920 tStdout = (HANDLE) _beginthreadex( 0, 1024,
921 (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0,
923 tStderr = (HANDLE) _beginthreadex( 0, 1024,
924 (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,
927 if (tStdout == 0 || tStderr == 0) {
929 pproc->last_err = GetLastError();
930 pproc->lerrno = E_SCALL;
936 * Wait for all I/O to finish and for the child process to exit
939 while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {
942 wait_list[wait_count++] = tStdin;
945 wait_list[wait_count++] = tStdout;
948 wait_list[wait_count++] = tStderr;
951 wait_list[wait_count++] = childhand;
954 wait_return = WaitForMultipleObjects(wait_count, wait_list,
955 FALSE, /* don't wait for all: one ready will do */
956 child_dead? 1000 :INFINITE); /* after the child dies, subthreads have
957 one second to collect all remaining output */
959 if (wait_return == WAIT_FAILED) {
960 /* map_windows32_error_to_string(GetLastError());*/
961 pproc->last_err = GetLastError();
962 pproc->lerrno = E_SCALL;
966 ready_hand = wait_list[wait_return - WAIT_OBJECT_0];
968 if (ready_hand == tStdin) {
969 CloseHandle((HANDLE)pproc->sv_stdin[0]);
970 pproc->sv_stdin[0] = 0;
975 } else if (ready_hand == tStdout) {
977 CloseHandle((HANDLE)pproc->sv_stdout[0]);
978 pproc->sv_stdout[0] = 0;
979 CloseHandle(tStdout);
983 } else if (ready_hand == tStderr) {
985 CloseHandle((HANDLE)pproc->sv_stderr[0]);
986 pproc->sv_stderr[0] = 0;
987 CloseHandle(tStderr);
991 } else if (ready_hand == childhand) {
994 GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
995 if (ierr == CONTROL_C_EXIT) {
996 pproc->signal = SIGINT;
998 pproc->exit_code = ierr;
1000 if (GetExitCodeResult == FALSE) {
1001 pproc->last_err = GetLastError();
1002 pproc->lerrno = E_SCALL;
1009 /* ?? Got back a handle we didn't query ?? */
1010 pproc->last_err = 0;
1011 pproc->lerrno = E_FAIL;
1018 CloseHandle(tStdin);
1020 CloseHandle(tStdout);
1022 CloseHandle(tStderr);
1033 * Purpose: collects output from child process and returns results
1039 * Notes/Dependencies:
1048 BOOL GetExitCodeResult;
1052 pproc = process_wait_for_any_private(1, 0);
1054 pproc = (sub_process *)proc;
1056 /* some sort of internal error */
1060 childhand = (HANDLE) pproc->pid;
1063 * This function is poorly named, and could also be used just to wait
1064 * for child death if you're doing your own pipe I/O. If that is
1065 * the case, close the pipe handles here.
1067 if (pproc->sv_stdin[0]) {
1068 CloseHandle((HANDLE)pproc->sv_stdin[0]);
1069 pproc->sv_stdin[0] = 0;
1071 if (pproc->sv_stdout[0]) {
1072 CloseHandle((HANDLE)pproc->sv_stdout[0]);
1073 pproc->sv_stdout[0] = 0;
1075 if (pproc->sv_stderr[0]) {
1076 CloseHandle((HANDLE)pproc->sv_stderr[0]);
1077 pproc->sv_stderr[0] = 0;
1081 * Wait for the child process to exit
1084 wait_return = WaitForSingleObject(childhand, INFINITE);
1086 if (wait_return != WAIT_OBJECT_0) {
1087 /* map_windows32_error_to_string(GetLastError());*/
1088 pproc->last_err = GetLastError();
1089 pproc->lerrno = E_SCALL;
1093 GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
1094 if (ierr == CONTROL_C_EXIT) {
1095 pproc->signal = SIGINT;
1097 pproc->exit_code = ierr;
1099 if (GetExitCodeResult == FALSE) {
1100 pproc->last_err = GetLastError();
1101 pproc->lerrno = E_SCALL;
1113 * Description: Clean up any leftover handles, etc. It is up to the
1114 * caller to manage and free the input, output, and stderr buffers.
1120 sub_process *pproc = (sub_process *)proc;
1123 if (pproc->using_pipes) {
1124 for (i= 0; i <= 1; i++) {
1125 if ((HANDLE)pproc->sv_stdin[i]
1126 && (HANDLE)pproc->sv_stdin[i] != INVALID_HANDLE_VALUE)
1127 CloseHandle((HANDLE)pproc->sv_stdin[i]);
1128 if ((HANDLE)pproc->sv_stdout[i]
1129 && (HANDLE)pproc->sv_stdout[i] != INVALID_HANDLE_VALUE)
1130 CloseHandle((HANDLE)pproc->sv_stdout[i]);
1131 if ((HANDLE)pproc->sv_stderr[i]
1132 && (HANDLE)pproc->sv_stderr[i] != INVALID_HANDLE_VALUE)
1133 CloseHandle((HANDLE)pproc->sv_stderr[i]);
1136 if ((HANDLE)pproc->pid)
1137 CloseHandle((HANDLE)pproc->pid);
1145 * Create a command line buffer to pass to CreateProcess
1147 * Returns: the buffer or NULL for failure
1148 * Shell case: sh_name a:/full/path/to/script argv[1] argv[2] ...
1149 * Otherwise: argv[0] argv[1] argv[2] ...
1151 * Notes/Dependencies:
1152 * CreateProcess does not take an argv, so this command creates a
1153 * command line for the executable.
1157 make_command_line( char *shell_name, char *full_exec_path, char **argv)
1161 int* enclose_in_quotes = NULL;
1162 int* enclose_in_quotes_i;
1163 unsigned int bytes_required = 0;
1165 char* command_line_i;
1166 int cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */
1167 int have_sh = 0; /* HAVE_CYGWIN_SHELL */
1169 #ifdef HAVE_CYGWIN_SHELL
1170 have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe"));
1174 if (shell_name && full_exec_path) {
1176 = strlen(shell_name) + 1 + strlen(full_exec_path);
1178 * Skip argv[0] if any, when shell_name is given.
1182 * Add one for the intervening space.
1184 if (*argv) bytes_required++;
1188 while (*(argvi++)) argc++;
1191 enclose_in_quotes = (int*) calloc(1, argc * sizeof(int));
1193 if (!enclose_in_quotes) {
1198 /* We have to make one pass through each argv[i] to see if we need
1199 * to enclose it in ", so we might as well figure out how much
1200 * memory we'll need on the same pass.
1204 enclose_in_quotes_i = enclose_in_quotes;
1207 unsigned int backslash_count = 0;
1210 * We have to enclose empty arguments in ".
1212 if (!(*p)) *enclose_in_quotes_i = 1;
1218 * We have to insert a backslash for each "
1219 * and each \ that precedes the ".
1221 bytes_required += (backslash_count + 1);
1222 backslash_count = 0;
1225 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1231 * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
1232 * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
1233 * that argv in always equals argv out. This was removed. Say you have
1234 * such a program named glob.exe. You enter
1236 * at the sh command prompt. Obviously the intent is to make glob do the
1237 * wildcarding instead of sh. If we set *enclose_in_quotes_i for '*' or '?',
1238 * then the command line that glob would see would be
1240 * and the _setargv in SETARGV.OBJ would _not_ expand the *.
1244 *enclose_in_quotes_i = 1;
1248 backslash_count = 0;
1253 * Add one for each character in argv[i].
1260 if (*enclose_in_quotes_i) {
1262 * Add one for each enclosing ",
1263 * and one for each \ that precedes the
1266 bytes_required += (backslash_count + 2);
1270 * Add one for the intervening space.
1272 if (*(++argvi)) bytes_required++;
1273 enclose_in_quotes_i++;
1277 * Add one for the terminating NULL.
1281 command_line = (char*) malloc(bytes_required);
1283 if (!command_line) {
1284 if (enclose_in_quotes) free(enclose_in_quotes);
1288 command_line_i = command_line;
1290 if (shell_name && full_exec_path) {
1291 while(*shell_name) {
1292 *(command_line_i++) = *(shell_name++);
1295 *(command_line_i++) = ' ';
1297 while(*full_exec_path) {
1298 *(command_line_i++) = *(full_exec_path++);
1302 *(command_line_i++) = ' ';
1307 enclose_in_quotes_i = enclose_in_quotes;
1311 unsigned int backslash_count = 0;
1313 if (*enclose_in_quotes_i) {
1314 *(command_line_i++) = '\"';
1319 if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */
1320 /* instead of a \", cygwin likes "" */
1321 *(command_line_i++) = '\"';
1325 * We have to insert a backslash for the "
1326 * and each \ that precedes the ".
1330 while(backslash_count) {
1331 *(command_line_i++) = '\\';
1335 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1336 } else if (*p == '\\') {
1339 backslash_count = 0;
1344 * Copy the character.
1346 *(command_line_i++) = *(p++);
1349 if (*enclose_in_quotes_i) {
1350 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1352 * Add one \ for each \ that precedes the
1355 while(backslash_count--) {
1356 *(command_line_i++) = '\\';
1359 *(command_line_i++) = '\"';
1363 * Append an intervening space.
1366 *(command_line_i++) = ' ';
1369 enclose_in_quotes_i++;
1373 * Append the terminating NULL.
1375 *command_line_i = '\0';
1377 if (enclose_in_quotes) free(enclose_in_quotes);
1378 return command_line;
1382 * Description: Given an argv and optional envp, launch the process
1383 * using the default stdin, stdout, and stderr handles.
1384 * Also, register process so that process_wait_for_any_private()
1385 * can be used via process_file_io(NULL) or
1386 * process_wait_for_any().
1390 * Notes/Dependencies:
1399 HANDLE hIn = INVALID_HANDLE_VALUE;
1400 HANDLE hOut = INVALID_HANDLE_VALUE;
1401 HANDLE hErr = INVALID_HANDLE_VALUE;
1402 HANDLE hProcess, tmpIn, tmpOut, tmpErr;
1405 if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
1406 DB (DB_JOBS, ("process_easy: All process slots used up\n"));
1407 return INVALID_HANDLE_VALUE;
1409 /* Standard handles returned by GetStdHandle can be NULL or
1410 INVALID_HANDLE_VALUE if the parent process closed them. If that
1411 happens, we open the null device and pass its handle to
1412 CreateProcess as the corresponding handle to inherit. */
1413 tmpIn = GetStdHandle(STD_INPUT_HANDLE);
1414 if (DuplicateHandle(GetCurrentProcess(),
1416 GetCurrentProcess(),
1420 DUPLICATE_SAME_ACCESS) == FALSE) {
1421 if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
1422 tmpIn = CreateFile("NUL", GENERIC_READ,
1423 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1424 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1425 if (tmpIn != INVALID_HANDLE_VALUE
1426 && DuplicateHandle(GetCurrentProcess(),
1428 GetCurrentProcess(),
1432 DUPLICATE_SAME_ACCESS) == FALSE)
1435 if (hIn == INVALID_HANDLE_VALUE) {
1436 fprintf(stderr, "process_easy: DuplicateHandle(In) failed (e=%ld)\n", e);
1437 return INVALID_HANDLE_VALUE;
1441 tmpOut = (HANDLE)_get_osfhandle (outfd);
1443 tmpOut = GetStdHandle (STD_OUTPUT_HANDLE);
1444 if (DuplicateHandle(GetCurrentProcess(),
1446 GetCurrentProcess(),
1450 DUPLICATE_SAME_ACCESS) == FALSE) {
1451 if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
1452 tmpOut = CreateFile("NUL", GENERIC_WRITE,
1453 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1454 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1455 if (tmpOut != INVALID_HANDLE_VALUE
1456 && DuplicateHandle(GetCurrentProcess(),
1458 GetCurrentProcess(),
1462 DUPLICATE_SAME_ACCESS) == FALSE)
1463 CloseHandle(tmpOut);
1465 if (hOut == INVALID_HANDLE_VALUE) {
1466 fprintf(stderr, "process_easy: DuplicateHandle(Out) failed (e=%ld)\n", e);
1467 return INVALID_HANDLE_VALUE;
1471 tmpErr = (HANDLE)_get_osfhandle (errfd);
1473 tmpErr = GetStdHandle(STD_ERROR_HANDLE);
1474 if (DuplicateHandle(GetCurrentProcess(),
1476 GetCurrentProcess(),
1480 DUPLICATE_SAME_ACCESS) == FALSE) {
1481 if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
1482 tmpErr = CreateFile("NUL", GENERIC_WRITE,
1483 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1484 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1485 if (tmpErr != INVALID_HANDLE_VALUE
1486 && DuplicateHandle(GetCurrentProcess(),
1488 GetCurrentProcess(),
1492 DUPLICATE_SAME_ACCESS) == FALSE)
1493 CloseHandle(tmpErr);
1495 if (hErr == INVALID_HANDLE_VALUE) {
1496 fprintf(stderr, "process_easy: DuplicateHandle(Err) failed (e=%ld)\n", e);
1497 return INVALID_HANDLE_VALUE;
1501 hProcess = process_init_fd(hIn, hOut, hErr);
1503 if (process_begin(hProcess, argv, envp, argv[0], NULL)) {
1504 fake_exits_pending++;
1505 /* process_begin() failed: make a note of that. */
1506 if (!((sub_process*) hProcess)->last_err)
1507 ((sub_process*) hProcess)->last_err = -1;
1508 ((sub_process*) hProcess)->exit_code = process_last_err(hProcess);
1510 /* close up unused handles */
1511 if (hIn != INVALID_HANDLE_VALUE)
1513 if (hOut != INVALID_HANDLE_VALUE)
1515 if (hErr != INVALID_HANDLE_VALUE)
1519 process_register(hProcess);