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;
62 * When a process has been waited for, adjust the wait state
63 * array so that we don't wait for it again
66 process_adjust_wait_state(sub_process
* pproc
)
73 for (i
= 0; i
< proc_index
; i
++)
74 if (proc_array
[i
]->pid
== pproc
->pid
)
80 memmove(&proc_array
[i
], &proc_array
[i
+1],
81 (proc_index
-i
) * sizeof(sub_process
*));
82 proc_array
[proc_index
] = NULL
;
87 * Waits for any of the registered child processes to finish.
90 process_wait_for_any_private(void)
92 HANDLE handles
[MAXIMUM_WAIT_OBJECTS
];
99 /* build array of handles to wait for */
100 for (i
= 0; i
< proc_index
; i
++) {
101 handles
[i
] = (HANDLE
) proc_array
[i
]->pid
;
103 if (fake_exits_pending
&& proc_array
[i
]->exit_code
)
107 /* wait for someone to exit */
108 if (!fake_exits_pending
) {
109 retval
= WaitForMultipleObjects(proc_index
, handles
, FALSE
, INFINITE
);
110 which
= retval
- WAIT_OBJECT_0
;
112 fake_exits_pending
--;
113 retval
= !WAIT_FAILED
;
117 /* return pointer to process */
118 if (retval
!= WAIT_FAILED
) {
119 sub_process
* pproc
= proc_array
[which
];
120 process_adjust_wait_state(pproc
);
127 * Terminate a process.
130 process_kill(HANDLE proc
, int signal
)
132 sub_process
* pproc
= (sub_process
*) proc
;
133 pproc
->signal
= signal
;
134 return (TerminateProcess((HANDLE
) pproc
->pid
, signal
));
138 * Use this function to register processes you wish to wait for by
139 * calling process_file_io(NULL) or process_wait_any(). This must be done
140 * because it is possible for callers of this library to reuse the same
141 * handle for multiple processes launches :-(
144 process_register(HANDLE proc
)
146 if (proc_index
< MAXIMUM_WAIT_OBJECTS
)
147 proc_array
[proc_index
++] = (sub_process
*) proc
;
151 * Return the number of processes that we are still waiting for.
154 process_used_slots(void)
160 * Public function which works kind of like waitpid(). Wait for any
161 * of the children to die and return results. To call this function,
162 * you must do 1 of things:
164 * x = process_easy(...);
168 * x = process_init_fd();
169 * process_register(x);
173 * x = process_init();
174 * process_register(x);
176 * You must NOT then call process_pipe_io() because this function is
177 * not capable of handling automatic notification of any child
182 process_wait_for_any(void)
184 sub_process
* pproc
= process_wait_for_any_private();
190 * Ouch! can't tell caller if this fails directly. Caller
191 * will have to use process_last_err()
193 (void) process_file_io(pproc
);
194 return ((HANDLE
) pproc
);
199 process_signal(HANDLE proc
)
201 if (proc
== INVALID_HANDLE_VALUE
) return 0;
202 return (((sub_process
*)proc
)->signal
);
206 process_last_err(HANDLE proc
)
208 if (proc
== INVALID_HANDLE_VALUE
) return ERROR_INVALID_HANDLE
;
209 return (((sub_process
*)proc
)->last_err
);
213 process_exit_code(HANDLE proc
)
215 if (proc
== INVALID_HANDLE_VALUE
) return EXIT_FAILURE
;
216 return (((sub_process
*)proc
)->exit_code
);
221 All the following functions are currently unused.
222 All of them would crash gmake if called with argument INVALID_HANDLE_VALUE.
223 Hence whoever wants to use one of this functions must invent and implement
224 a reasonable error handling for this function.
227 process_outbuf(HANDLE proc)
229 return (((sub_process *)proc)->outp);
233 process_errbuf(HANDLE proc)
235 return (((sub_process *)proc)->errp);
239 process_outcnt(HANDLE proc)
241 return (((sub_process *)proc)->outcnt);
245 process_errcnt(HANDLE proc)
247 return (((sub_process *)proc)->errcnt);
251 process_pipes(HANDLE proc, int pipes[3])
253 pipes[0] = ((sub_process *)proc)->sv_stdin[0];
254 pipes[1] = ((sub_process *)proc)->sv_stdout[0];
255 pipes[2] = ((sub_process *)proc)->sv_stderr[0];
265 * open file descriptors for attaching stdin/stdout/sterr
267 HANDLE stdin_pipes
[2];
268 HANDLE stdout_pipes
[2];
269 HANDLE stderr_pipes
[2];
270 SECURITY_ATTRIBUTES inherit
;
271 BYTE sd
[SECURITY_DESCRIPTOR_MIN_LENGTH
];
273 pproc
= malloc(sizeof(*pproc
));
274 memset(pproc
, 0, sizeof(*pproc
));
276 /* We can't use NULL for lpSecurityDescriptor because that
277 uses the default security descriptor of the calling process.
278 Instead we use a security descriptor with no DACL. This
279 allows nonrestricted access to the associated objects. */
281 if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR
)(&sd
),
282 SECURITY_DESCRIPTOR_REVISION
)) {
283 pproc
->last_err
= GetLastError();
284 pproc
->lerrno
= E_SCALL
;
285 return((HANDLE
)pproc
);
288 inherit
.nLength
= sizeof(inherit
);
289 inherit
.lpSecurityDescriptor
= (PSECURITY_DESCRIPTOR
)(&sd
);
290 inherit
.bInheritHandle
= TRUE
;
292 // By convention, parent gets pipe[0], and child gets pipe[1]
293 // This means the READ side of stdin pipe goes into pipe[1]
294 // and the WRITE side of the stdout and stderr pipes go into pipe[1]
295 if (CreatePipe( &stdin_pipes
[1], &stdin_pipes
[0], &inherit
, 0) == FALSE
||
296 CreatePipe( &stdout_pipes
[0], &stdout_pipes
[1], &inherit
, 0) == FALSE
||
297 CreatePipe( &stderr_pipes
[0], &stderr_pipes
[1], &inherit
, 0) == FALSE
) {
299 pproc
->last_err
= GetLastError();
300 pproc
->lerrno
= E_SCALL
;
301 return((HANDLE
)pproc
);
305 // Mark the parent sides of the pipes as non-inheritable
307 if (SetHandleInformation(stdin_pipes
[0],
308 HANDLE_FLAG_INHERIT
, 0) == FALSE
||
309 SetHandleInformation(stdout_pipes
[0],
310 HANDLE_FLAG_INHERIT
, 0) == FALSE
||
311 SetHandleInformation(stderr_pipes
[0],
312 HANDLE_FLAG_INHERIT
, 0) == FALSE
) {
314 pproc
->last_err
= GetLastError();
315 pproc
->lerrno
= E_SCALL
;
316 return((HANDLE
)pproc
);
318 pproc
->sv_stdin
[0] = (intptr_t) stdin_pipes
[0];
319 pproc
->sv_stdin
[1] = (intptr_t) stdin_pipes
[1];
320 pproc
->sv_stdout
[0] = (intptr_t) stdout_pipes
[0];
321 pproc
->sv_stdout
[1] = (intptr_t) stdout_pipes
[1];
322 pproc
->sv_stderr
[0] = (intptr_t) stderr_pipes
[0];
323 pproc
->sv_stderr
[1] = (intptr_t) stderr_pipes
[1];
325 pproc
->using_pipes
= 1;
329 return((HANDLE
)pproc
);
334 process_init_fd(HANDLE stdinh
, HANDLE stdouth
, HANDLE stderrh
)
338 pproc
= malloc(sizeof(*pproc
));
339 memset(pproc
, 0, sizeof(*pproc
));
342 * Just pass the provided file handles to the 'child side' of the
343 * pipe, bypassing pipes altogether.
345 pproc
->sv_stdin
[1] = (intptr_t) stdinh
;
346 pproc
->sv_stdout
[1] = (intptr_t) stdouth
;
347 pproc
->sv_stderr
[1] = (intptr_t) stderrh
;
349 pproc
->last_err
= pproc
->lerrno
= 0;
351 return((HANDLE
)pproc
);
356 find_file(const char *exec_path
, const char *path_var
,
357 char *full_fname
, DWORD full_len
)
364 static const char *extensions
[] =
365 /* Should .com come before no-extension case? */
366 { ".exe", ".cmd", ".bat", "", ".com", NULL
};
368 fname
= xmalloc(strlen(exec_path
) + 5);
369 strcpy(fname
, exec_path
);
370 ext
= fname
+ strlen(fname
);
372 for (i
= 0; extensions
[i
]; i
++) {
373 strcpy(ext
, extensions
[i
]);
374 if (((req_len
= SearchPath (path_var
, fname
, NULL
, full_len
,
375 full_fname
, NULL
)) > 0
376 /* For compatibility with previous code, which
377 used OpenFile, and with Windows operation in
378 general, also look in various default
379 locations, such as Windows directory and
380 Windows System directory. Warning: this also
381 searches PATH in the Make's environment, which
382 might not be what the Makefile wants, but it
383 seems to be OK as a fallback, after the
384 previous SearchPath failed to find on child's
386 || (req_len
= SearchPath (NULL
, fname
, NULL
, full_len
,
387 full_fname
, NULL
)) > 0)
388 && req_len
<= full_len
390 CreateFile(full_fname
,
392 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
395 FILE_ATTRIBUTE_NORMAL
,
396 NULL
)) != INVALID_HANDLE_VALUE
) {
403 return INVALID_HANDLE_VALUE
;
408 * Description: Create the child process to be helped
410 * Returns: success <=> 0
412 * Notes/Dependencies:
422 sub_process
*pproc
= (sub_process
*)proc
;
423 char *shell_name
= 0;
424 int file_not_found
=0;
426 char exec_fname
[MAX_PATH
];
427 const char *path_var
= NULL
;
430 DWORD bytes_returned
;
433 STARTUPINFO startInfo
;
434 PROCESS_INFORMATION procInfo
;
438 * Shell script detection... if the exec_path starts with #! then
439 * we want to exec shell-script-name exec-path, not just exec-path
440 * NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl. We do not
441 * hard-code the path to the shell or perl or whatever: Instead, we
442 * assume it's in the path somewhere (generally, the NT tools
446 /* Use the Makefile's value of PATH to look for the program to
447 execute, because it could be different from Make's PATH
448 (e.g., if the target sets its own value. */
450 for (ep
= envp
; *ep
; ep
++) {
451 if (strncmp (*ep
, "PATH=", 5) == 0
452 || strncmp (*ep
, "Path=", 5) == 0) {
457 exec_handle
= find_file(exec_path
, path_var
,
458 exec_fname
, sizeof(exec_fname
));
461 * If we couldn't open the file, just assume that Windows will be
462 * somehow able to find and execute it.
464 if (exec_handle
== INVALID_HANDLE_VALUE
) {
468 /* Attempt to read the first line of the file */
469 if (ReadFile( exec_handle
,
470 buf
, sizeof(buf
) - 1, /* leave room for trailing NULL */
471 &bytes_returned
, 0) == FALSE
|| bytes_returned
< 2) {
473 pproc
->last_err
= GetLastError();
474 pproc
->lerrno
= E_IO
;
475 CloseHandle(exec_handle
);
478 if (buf
[0] == '#' && buf
[1] == '!') {
480 * This is a shell script... Change the command line from
481 * exec_path args to shell_name exec_path args
485 /* Make sure buf is NULL terminated */
486 buf
[bytes_returned
] = 0;
488 * Depending on the file system type, etc. the first line
489 * of the shell script may end with newline or newline-carriage-return
490 * Whatever it ends with, cut it off.
492 p
= strchr(buf
, '\n');
495 p
= strchr(buf
, '\r');
500 * Find base name of shell
502 shell_name
= strrchr( buf
, '/');
506 shell_name
= &buf
[2];/* skipping "#!" */
510 CloseHandle(exec_handle
);
516 command_line
= make_command_line( shell_name
, exec_path
, argv
);
518 command_line
= make_command_line( shell_name
, exec_fname
, argv
);
520 if ( command_line
== NULL
) {
522 pproc
->lerrno
= E_NO_MEM
;
527 if (arr2envblk(envp
, &envblk
) ==FALSE
) {
529 pproc
->lerrno
= E_NO_MEM
;
530 free( command_line
);
535 if ((shell_name
) || (file_not_found
)) {
536 exec_path
= 0; /* Search for the program in %Path% */
538 exec_path
= exec_fname
;
542 * Set up inherited stdin, stdout, stderr for child
544 GetStartupInfo(&startInfo
);
545 startInfo
.dwFlags
= STARTF_USESTDHANDLES
;
546 startInfo
.lpReserved
= 0;
547 startInfo
.cbReserved2
= 0;
548 startInfo
.lpReserved2
= 0;
549 startInfo
.lpTitle
= shell_name
? shell_name
: exec_path
;
550 startInfo
.hStdInput
= (HANDLE
)pproc
->sv_stdin
[1];
551 startInfo
.hStdOutput
= (HANDLE
)pproc
->sv_stdout
[1];
552 startInfo
.hStdError
= (HANDLE
)pproc
->sv_stderr
[1];
555 if (envblk
) free(envblk
);
558 DB (DB_JOBS
, ("CreateProcess(%s,%s,...)\n",
559 exec_path
? exec_path
: "NULL",
560 command_line
? command_line
: "NULL"));
565 0, /* default security attributes for thread */
566 TRUE
, /* inherit handles (e.g. helper pipes, oserv socket) */
569 0, /* default starting directory */
571 &procInfo
) == FALSE
) {
573 pproc
->last_err
= GetLastError();
574 pproc
->lerrno
= E_FORK
;
575 fprintf(stderr
, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
576 exec_path
? exec_path
: "NULL", command_line
);
577 if (envblk
) free(envblk
);
578 free( command_line
);
583 pproc
->pid
= (pid_t
)procInfo
.hProcess
;
584 /* Close the thread handle -- we'll just watch the process */
585 CloseHandle(procInfo
.hThread
);
587 /* Close the halves of the pipes we don't need */
588 CloseHandle((HANDLE
)pproc
->sv_stdin
[1]);
589 CloseHandle((HANDLE
)pproc
->sv_stdout
[1]);
590 CloseHandle((HANDLE
)pproc
->sv_stderr
[1]);
591 pproc
->sv_stdin
[1] = 0;
592 pproc
->sv_stdout
[1] = 0;
593 pproc
->sv_stderr
[1] = 0;
595 free( command_line
);
596 if (envblk
) free(envblk
);
604 proc_stdin_thread(sub_process
*pproc
)
608 if (WriteFile( (HANDLE
) pproc
->sv_stdin
[0], pproc
->inp
, pproc
->incnt
,
609 &in_done
, NULL
) == FALSE
)
611 // This if should never be true for anonymous pipes, but gives
612 // us a chance to change I/O mechanisms later
613 if (in_done
< pproc
->incnt
) {
614 pproc
->incnt
-= in_done
;
615 pproc
->inp
+= in_done
;
620 return 0; // for compiler warnings only.. not reached
624 proc_stdout_thread(sub_process
*pproc
)
626 DWORD bufsize
= 1024;
629 pproc
->outp
= malloc(bufsize
);
630 if (pproc
->outp
== NULL
)
635 if (ReadFile( (HANDLE
)pproc
->sv_stdout
[0], &c
, 1, &nread
, NULL
)
637 /* map_windows32_error_to_string(GetLastError());*/
642 if (pproc
->outcnt
+ nread
> bufsize
) {
643 bufsize
+= nread
+ 512;
644 pproc
->outp
= realloc(pproc
->outp
, bufsize
);
645 if (pproc
->outp
== NULL
) {
650 pproc
->outp
[pproc
->outcnt
++] = c
;
656 proc_stderr_thread(sub_process
*pproc
)
658 DWORD bufsize
= 1024;
661 pproc
->errp
= malloc(bufsize
);
662 if (pproc
->errp
== NULL
)
667 if (ReadFile( (HANDLE
)pproc
->sv_stderr
[0], &c
, 1, &nread
, NULL
) == FALSE
) {
668 map_windows32_error_to_string(GetLastError());
673 if (pproc
->errcnt
+ nread
> bufsize
) {
674 bufsize
+= nread
+ 512;
675 pproc
->errp
= realloc(pproc
->errp
, bufsize
);
676 if (pproc
->errp
== NULL
) {
681 pproc
->errp
[pproc
->errcnt
++] = c
;
688 * Purpose: collects output from child process and returns results
694 * Notes/Dependencies:
702 sub_process
*pproc
= (sub_process
*)proc
;
703 bool_t stdin_eof
= FALSE
, stdout_eof
= FALSE
, stderr_eof
= FALSE
;
704 HANDLE childhand
= (HANDLE
) pproc
->pid
;
705 HANDLE tStdin
= NULL
, tStdout
= NULL
, tStderr
= NULL
;
706 unsigned int dwStdin
, dwStdout
, dwStderr
;
711 bool_t child_dead
= FALSE
;
712 BOOL GetExitCodeResult
;
715 * Create stdin thread, if needed
717 pproc
->inp
= stdin_data
;
718 pproc
->incnt
= stdin_data_len
;
721 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
722 pproc
->sv_stdin
[0] = 0;
724 tStdin
= (HANDLE
) _beginthreadex( 0, 1024,
725 (unsigned (__stdcall
*) (void *))proc_stdin_thread
,
728 pproc
->last_err
= GetLastError();
729 pproc
->lerrno
= E_SCALL
;
735 * Assume child will produce stdout and stderr
737 tStdout
= (HANDLE
) _beginthreadex( 0, 1024,
738 (unsigned (__stdcall
*) (void *))proc_stdout_thread
, pproc
, 0,
740 tStderr
= (HANDLE
) _beginthreadex( 0, 1024,
741 (unsigned (__stdcall
*) (void *))proc_stderr_thread
, pproc
, 0,
744 if (tStdout
== 0 || tStderr
== 0) {
746 pproc
->last_err
= GetLastError();
747 pproc
->lerrno
= E_SCALL
;
753 * Wait for all I/O to finish and for the child process to exit
756 while (!stdin_eof
|| !stdout_eof
|| !stderr_eof
|| !child_dead
) {
759 wait_list
[wait_count
++] = tStdin
;
762 wait_list
[wait_count
++] = tStdout
;
765 wait_list
[wait_count
++] = tStderr
;
768 wait_list
[wait_count
++] = childhand
;
771 wait_return
= WaitForMultipleObjects(wait_count
, wait_list
,
772 FALSE
, /* don't wait for all: one ready will do */
773 child_dead
? 1000 :INFINITE
); /* after the child dies, subthreads have
774 one second to collect all remaining output */
776 if (wait_return
== WAIT_FAILED
) {
777 /* map_windows32_error_to_string(GetLastError());*/
778 pproc
->last_err
= GetLastError();
779 pproc
->lerrno
= E_SCALL
;
783 ready_hand
= wait_list
[wait_return
- WAIT_OBJECT_0
];
785 if (ready_hand
== tStdin
) {
786 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
787 pproc
->sv_stdin
[0] = 0;
792 } else if (ready_hand
== tStdout
) {
794 CloseHandle((HANDLE
)pproc
->sv_stdout
[0]);
795 pproc
->sv_stdout
[0] = 0;
796 CloseHandle(tStdout
);
800 } else if (ready_hand
== tStderr
) {
802 CloseHandle((HANDLE
)pproc
->sv_stderr
[0]);
803 pproc
->sv_stderr
[0] = 0;
804 CloseHandle(tStderr
);
808 } else if (ready_hand
== childhand
) {
811 GetExitCodeResult
= GetExitCodeProcess(childhand
, &ierr
);
812 if (ierr
== CONTROL_C_EXIT
) {
813 pproc
->signal
= SIGINT
;
815 pproc
->exit_code
= ierr
;
817 if (GetExitCodeResult
== FALSE
) {
818 pproc
->last_err
= GetLastError();
819 pproc
->lerrno
= E_SCALL
;
826 /* ?? Got back a handle we didn't query ?? */
828 pproc
->lerrno
= E_FAIL
;
837 CloseHandle(tStdout
);
839 CloseHandle(tStderr
);
849 * Purpose: collects output from child process and returns results
855 * Notes/Dependencies:
864 BOOL GetExitCodeResult
;
868 pproc
= process_wait_for_any_private();
870 pproc
= (sub_process
*)proc
;
872 /* some sort of internal error */
876 childhand
= (HANDLE
) pproc
->pid
;
879 * This function is poorly named, and could also be used just to wait
880 * for child death if you're doing your own pipe I/O. If that is
881 * the case, close the pipe handles here.
883 if (pproc
->sv_stdin
[0]) {
884 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
885 pproc
->sv_stdin
[0] = 0;
887 if (pproc
->sv_stdout
[0]) {
888 CloseHandle((HANDLE
)pproc
->sv_stdout
[0]);
889 pproc
->sv_stdout
[0] = 0;
891 if (pproc
->sv_stderr
[0]) {
892 CloseHandle((HANDLE
)pproc
->sv_stderr
[0]);
893 pproc
->sv_stderr
[0] = 0;
897 * Wait for the child process to exit
900 wait_return
= WaitForSingleObject(childhand
, INFINITE
);
902 if (wait_return
!= WAIT_OBJECT_0
) {
903 /* map_windows32_error_to_string(GetLastError());*/
904 pproc
->last_err
= GetLastError();
905 pproc
->lerrno
= E_SCALL
;
909 GetExitCodeResult
= GetExitCodeProcess(childhand
, &ierr
);
910 if (ierr
== CONTROL_C_EXIT
) {
911 pproc
->signal
= SIGINT
;
913 pproc
->exit_code
= ierr
;
915 if (GetExitCodeResult
== FALSE
) {
916 pproc
->last_err
= GetLastError();
917 pproc
->lerrno
= E_SCALL
;
929 * Description: Clean up any leftover handles, etc. It is up to the
930 * caller to manage and free the input, ouput, and stderr buffers.
936 sub_process
*pproc
= (sub_process
*)proc
;
939 if (pproc
->using_pipes
) {
940 for (i
= 0; i
<= 1; i
++) {
941 if ((HANDLE
)pproc
->sv_stdin
[i
])
942 CloseHandle((HANDLE
)pproc
->sv_stdin
[i
]);
943 if ((HANDLE
)pproc
->sv_stdout
[i
])
944 CloseHandle((HANDLE
)pproc
->sv_stdout
[i
]);
945 if ((HANDLE
)pproc
->sv_stderr
[i
])
946 CloseHandle((HANDLE
)pproc
->sv_stderr
[i
]);
949 if ((HANDLE
)pproc
->pid
)
950 CloseHandle((HANDLE
)pproc
->pid
);
958 * Create a command line buffer to pass to CreateProcess
960 * Returns: the buffer or NULL for failure
961 * Shell case: sh_name a:/full/path/to/script argv[1] argv[2] ...
962 * Otherwise: argv[0] argv[1] argv[2] ...
964 * Notes/Dependencies:
965 * CreateProcess does not take an argv, so this command creates a
966 * command line for the executable.
970 make_command_line( char *shell_name
, char *full_exec_path
, char **argv
)
974 int* enclose_in_quotes
= NULL
;
975 int* enclose_in_quotes_i
;
976 unsigned int bytes_required
= 0;
978 char* command_line_i
;
979 int cygwin_mode
= 0; /* HAVE_CYGWIN_SHELL */
980 int have_sh
= 0; /* HAVE_CYGWIN_SHELL */
982 #ifdef HAVE_CYGWIN_SHELL
983 have_sh
= (shell_name
!= NULL
|| strstr(full_exec_path
, "sh.exe"));
987 if (shell_name
&& full_exec_path
) {
989 = strlen(shell_name
) + 1 + strlen(full_exec_path
);
991 * Skip argv[0] if any, when shell_name is given.
995 * Add one for the intervening space.
997 if (*argv
) bytes_required
++;
1001 while (*(argvi
++)) argc
++;
1004 enclose_in_quotes
= (int*) calloc(1, argc
* sizeof(int));
1006 if (!enclose_in_quotes
) {
1011 /* We have to make one pass through each argv[i] to see if we need
1012 * to enclose it in ", so we might as well figure out how much
1013 * memory we'll need on the same pass.
1017 enclose_in_quotes_i
= enclose_in_quotes
;
1020 unsigned int backslash_count
= 0;
1023 * We have to enclose empty arguments in ".
1025 if (!(*p
)) *enclose_in_quotes_i
= 1;
1031 * We have to insert a backslash for each "
1032 * and each \ that precedes the ".
1034 bytes_required
+= (backslash_count
+ 1);
1035 backslash_count
= 0;
1038 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1044 * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
1045 * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
1046 * that argv in always equals argv out. This was removed. Say you have
1047 * such a program named glob.exe. You enter
1049 * at the sh command prompt. Obviously the intent is to make glob do the
1050 * wildcarding instead of sh. If we set *enclose_in_quotes_i for '*' or '?',
1051 * then the command line that glob would see would be
1053 * and the _setargv in SETARGV.OBJ would _not_ expand the *.
1057 *enclose_in_quotes_i
= 1;
1061 backslash_count
= 0;
1066 * Add one for each character in argv[i].
1073 if (*enclose_in_quotes_i
) {
1075 * Add one for each enclosing ",
1076 * and one for each \ that precedes the
1079 bytes_required
+= (backslash_count
+ 2);
1083 * Add one for the intervening space.
1085 if (*(++argvi
)) bytes_required
++;
1086 enclose_in_quotes_i
++;
1090 * Add one for the terminating NULL.
1094 command_line
= (char*) malloc(bytes_required
);
1096 if (!command_line
) {
1097 if (enclose_in_quotes
) free(enclose_in_quotes
);
1101 command_line_i
= command_line
;
1103 if (shell_name
&& full_exec_path
) {
1104 while(*shell_name
) {
1105 *(command_line_i
++) = *(shell_name
++);
1108 *(command_line_i
++) = ' ';
1110 while(*full_exec_path
) {
1111 *(command_line_i
++) = *(full_exec_path
++);
1115 *(command_line_i
++) = ' ';
1120 enclose_in_quotes_i
= enclose_in_quotes
;
1124 unsigned int backslash_count
= 0;
1126 if (*enclose_in_quotes_i
) {
1127 *(command_line_i
++) = '\"';
1132 if (cygwin_mode
&& have_sh
) { /* HAVE_CYGWIN_SHELL */
1133 /* instead of a \", cygwin likes "" */
1134 *(command_line_i
++) = '\"';
1138 * We have to insert a backslash for the "
1139 * and each \ that precedes the ".
1143 while(backslash_count
) {
1144 *(command_line_i
++) = '\\';
1148 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1149 } else if (*p
== '\\') {
1152 backslash_count
= 0;
1157 * Copy the character.
1159 *(command_line_i
++) = *(p
++);
1162 if (*enclose_in_quotes_i
) {
1163 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1165 * Add one \ for each \ that precedes the
1168 while(backslash_count
--) {
1169 *(command_line_i
++) = '\\';
1172 *(command_line_i
++) = '\"';
1176 * Append an intervening space.
1179 *(command_line_i
++) = ' ';
1182 enclose_in_quotes_i
++;
1186 * Append the terminating NULL.
1188 *command_line_i
= '\0';
1190 if (enclose_in_quotes
) free(enclose_in_quotes
);
1191 return command_line
;
1195 * Description: Given an argv and optional envp, launch the process
1196 * using the default stdin, stdout, and stderr handles.
1197 * Also, register process so that process_wait_for_any_private()
1198 * can be used via process_file_io(NULL) or
1199 * process_wait_for_any().
1203 * Notes/Dependencies:
1215 if (proc_index
>= MAXIMUM_WAIT_OBJECTS
) {
1216 DB (DB_JOBS
, ("process_easy: All process slots used up\n"));
1217 return INVALID_HANDLE_VALUE
;
1219 if (DuplicateHandle(GetCurrentProcess(),
1220 GetStdHandle(STD_INPUT_HANDLE
),
1221 GetCurrentProcess(),
1225 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1227 "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
1229 return INVALID_HANDLE_VALUE
;
1231 if (DuplicateHandle(GetCurrentProcess(),
1232 GetStdHandle(STD_OUTPUT_HANDLE
),
1233 GetCurrentProcess(),
1237 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1239 "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
1241 return INVALID_HANDLE_VALUE
;
1243 if (DuplicateHandle(GetCurrentProcess(),
1244 GetStdHandle(STD_ERROR_HANDLE
),
1245 GetCurrentProcess(),
1249 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1251 "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
1253 return INVALID_HANDLE_VALUE
;
1256 hProcess
= process_init_fd(hIn
, hOut
, hErr
);
1258 if (process_begin(hProcess
, argv
, envp
, argv
[0], NULL
)) {
1259 fake_exits_pending
++;
1260 /* process_begin() failed: make a note of that. */
1261 if (!((sub_process
*) hProcess
)->last_err
)
1262 ((sub_process
*) hProcess
)->last_err
= -1;
1263 ((sub_process
*) hProcess
)->exit_code
= process_last_err(hProcess
);
1265 /* close up unused handles */
1271 process_register(hProcess
);