1 /* Process handling for Windows.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007 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/>. */
20 #include <process.h> /* for msvc _beginthreadex, _endthreadex */
30 static char *make_command_line(char *shell_name
, char *exec_path
, char **argv
);
32 typedef struct sub_process_t
{
40 volatile DWORD outcnt
;
42 volatile DWORD errcnt
;
50 /* keep track of children so we can implement a waitpid-like routine */
51 static sub_process
*proc_array
[MAXIMUM_WAIT_OBJECTS
];
52 static int proc_index
= 0;
53 static int fake_exits_pending
= 0;
56 * When a process has been waited for, adjust the wait state
57 * array so that we don't wait for it again
60 process_adjust_wait_state(sub_process
* pproc
)
67 for (i
= 0; i
< proc_index
; i
++)
68 if (proc_array
[i
]->pid
== pproc
->pid
)
74 memmove(&proc_array
[i
], &proc_array
[i
+1],
75 (proc_index
-i
) * sizeof(sub_process
*));
76 proc_array
[proc_index
] = NULL
;
81 * Waits for any of the registered child processes to finish.
84 process_wait_for_any_private(void)
86 HANDLE handles
[MAXIMUM_WAIT_OBJECTS
];
93 /* build array of handles to wait for */
94 for (i
= 0; i
< proc_index
; i
++) {
95 handles
[i
] = (HANDLE
) proc_array
[i
]->pid
;
97 if (fake_exits_pending
&& proc_array
[i
]->exit_code
)
101 /* wait for someone to exit */
102 if (!fake_exits_pending
) {
103 retval
= WaitForMultipleObjects(proc_index
, handles
, FALSE
, INFINITE
);
104 which
= retval
- WAIT_OBJECT_0
;
106 fake_exits_pending
--;
107 retval
= !WAIT_FAILED
;
111 /* return pointer to process */
112 if (retval
!= WAIT_FAILED
) {
113 sub_process
* pproc
= proc_array
[which
];
114 process_adjust_wait_state(pproc
);
121 * Terminate a process.
124 process_kill(HANDLE proc
, int signal
)
126 sub_process
* pproc
= (sub_process
*) proc
;
127 pproc
->signal
= signal
;
128 return (TerminateProcess((HANDLE
) pproc
->pid
, signal
));
132 * Use this function to register processes you wish to wait for by
133 * calling process_file_io(NULL) or process_wait_any(). This must be done
134 * because it is possible for callers of this library to reuse the same
135 * handle for multiple processes launches :-(
138 process_register(HANDLE proc
)
140 if (proc_index
< MAXIMUM_WAIT_OBJECTS
)
141 proc_array
[proc_index
++] = (sub_process
*) proc
;
145 * Return the number of processes that we are still waiting for.
148 process_used_slots(void)
154 * Public function which works kind of like waitpid(). Wait for any
155 * of the children to die and return results. To call this function,
156 * you must do 1 of things:
158 * x = process_easy(...);
162 * x = process_init_fd();
163 * process_register(x);
167 * x = process_init();
168 * process_register(x);
170 * You must NOT then call process_pipe_io() because this function is
171 * not capable of handling automatic notification of any child
176 process_wait_for_any(void)
178 sub_process
* pproc
= process_wait_for_any_private();
184 * Ouch! can't tell caller if this fails directly. Caller
185 * will have to use process_last_err()
187 (void) process_file_io(pproc
);
188 return ((HANDLE
) pproc
);
193 process_signal(HANDLE proc
)
195 if (proc
== INVALID_HANDLE_VALUE
) return 0;
196 return (((sub_process
*)proc
)->signal
);
200 process_last_err(HANDLE proc
)
202 if (proc
== INVALID_HANDLE_VALUE
) return ERROR_INVALID_HANDLE
;
203 return (((sub_process
*)proc
)->last_err
);
207 process_exit_code(HANDLE proc
)
209 if (proc
== INVALID_HANDLE_VALUE
) return EXIT_FAILURE
;
210 return (((sub_process
*)proc
)->exit_code
);
215 All the following functions are currently unused.
216 All of them would crash gmake if called with argument INVALID_HANDLE_VALUE.
217 Hence whoever wants to use one of this functions must invent and implement
218 a reasonable error handling for this function.
221 process_outbuf(HANDLE proc)
223 return (((sub_process *)proc)->outp);
227 process_errbuf(HANDLE proc)
229 return (((sub_process *)proc)->errp);
233 process_outcnt(HANDLE proc)
235 return (((sub_process *)proc)->outcnt);
239 process_errcnt(HANDLE proc)
241 return (((sub_process *)proc)->errcnt);
245 process_pipes(HANDLE proc, int pipes[3])
247 pipes[0] = ((sub_process *)proc)->sv_stdin[0];
248 pipes[1] = ((sub_process *)proc)->sv_stdout[0];
249 pipes[2] = ((sub_process *)proc)->sv_stderr[0];
259 * open file descriptors for attaching stdin/stdout/sterr
261 HANDLE stdin_pipes
[2];
262 HANDLE stdout_pipes
[2];
263 HANDLE stderr_pipes
[2];
264 SECURITY_ATTRIBUTES inherit
;
265 BYTE sd
[SECURITY_DESCRIPTOR_MIN_LENGTH
];
267 pproc
= malloc(sizeof(*pproc
));
268 memset(pproc
, 0, sizeof(*pproc
));
270 /* We can't use NULL for lpSecurityDescriptor because that
271 uses the default security descriptor of the calling process.
272 Instead we use a security descriptor with no DACL. This
273 allows nonrestricted access to the associated objects. */
275 if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR
)(&sd
),
276 SECURITY_DESCRIPTOR_REVISION
)) {
277 pproc
->last_err
= GetLastError();
278 pproc
->lerrno
= E_SCALL
;
279 return((HANDLE
)pproc
);
282 inherit
.nLength
= sizeof(inherit
);
283 inherit
.lpSecurityDescriptor
= (PSECURITY_DESCRIPTOR
)(&sd
);
284 inherit
.bInheritHandle
= TRUE
;
286 // By convention, parent gets pipe[0], and child gets pipe[1]
287 // This means the READ side of stdin pipe goes into pipe[1]
288 // and the WRITE side of the stdout and stderr pipes go into pipe[1]
289 if (CreatePipe( &stdin_pipes
[1], &stdin_pipes
[0], &inherit
, 0) == FALSE
||
290 CreatePipe( &stdout_pipes
[0], &stdout_pipes
[1], &inherit
, 0) == FALSE
||
291 CreatePipe( &stderr_pipes
[0], &stderr_pipes
[1], &inherit
, 0) == FALSE
) {
293 pproc
->last_err
= GetLastError();
294 pproc
->lerrno
= E_SCALL
;
295 return((HANDLE
)pproc
);
299 // Mark the parent sides of the pipes as non-inheritable
301 if (SetHandleInformation(stdin_pipes
[0],
302 HANDLE_FLAG_INHERIT
, 0) == FALSE
||
303 SetHandleInformation(stdout_pipes
[0],
304 HANDLE_FLAG_INHERIT
, 0) == FALSE
||
305 SetHandleInformation(stderr_pipes
[0],
306 HANDLE_FLAG_INHERIT
, 0) == FALSE
) {
308 pproc
->last_err
= GetLastError();
309 pproc
->lerrno
= E_SCALL
;
310 return((HANDLE
)pproc
);
312 pproc
->sv_stdin
[0] = (int) stdin_pipes
[0];
313 pproc
->sv_stdin
[1] = (int) stdin_pipes
[1];
314 pproc
->sv_stdout
[0] = (int) stdout_pipes
[0];
315 pproc
->sv_stdout
[1] = (int) stdout_pipes
[1];
316 pproc
->sv_stderr
[0] = (int) stderr_pipes
[0];
317 pproc
->sv_stderr
[1] = (int) stderr_pipes
[1];
319 pproc
->using_pipes
= 1;
323 return((HANDLE
)pproc
);
328 process_init_fd(HANDLE stdinh
, HANDLE stdouth
, HANDLE stderrh
)
332 pproc
= malloc(sizeof(*pproc
));
333 memset(pproc
, 0, sizeof(*pproc
));
336 * Just pass the provided file handles to the 'child side' of the
337 * pipe, bypassing pipes altogether.
339 pproc
->sv_stdin
[1] = (int) stdinh
;
340 pproc
->sv_stdout
[1] = (int) stdouth
;
341 pproc
->sv_stderr
[1] = (int) stderrh
;
343 pproc
->last_err
= pproc
->lerrno
= 0;
345 return((HANDLE
)pproc
);
350 find_file(char *exec_path
, LPOFSTRUCT file_info
)
356 fname
= malloc(strlen(exec_path
) + 5);
357 strcpy(fname
, exec_path
);
358 ext
= fname
+ strlen(fname
);
361 if ((exec_handle
= (HANDLE
)OpenFile(fname
, file_info
,
362 OF_READ
| OF_SHARE_COMPAT
)) != (HANDLE
)HFILE_ERROR
) {
368 if ((exec_handle
= (HANDLE
)OpenFile(fname
, file_info
,
369 OF_READ
| OF_SHARE_COMPAT
)) != (HANDLE
)HFILE_ERROR
) {
375 if ((exec_handle
= (HANDLE
)OpenFile(fname
, file_info
,
376 OF_READ
| OF_SHARE_COMPAT
)) != (HANDLE
)HFILE_ERROR
) {
381 /* should .com come before this case? */
382 if ((exec_handle
= (HANDLE
)OpenFile(exec_path
, file_info
,
383 OF_READ
| OF_SHARE_COMPAT
)) != (HANDLE
)HFILE_ERROR
) {
389 if ((exec_handle
= (HANDLE
)OpenFile(fname
, file_info
,
390 OF_READ
| OF_SHARE_COMPAT
)) != (HANDLE
)HFILE_ERROR
) {
401 * Description: Create the child process to be helped
403 * Returns: success <=> 0
405 * Notes/Dependencies:
415 sub_process
*pproc
= (sub_process
*)proc
;
416 char *shell_name
= 0;
417 int file_not_found
=0;
420 DWORD bytes_returned
;
423 STARTUPINFO startInfo
;
424 PROCESS_INFORMATION procInfo
;
430 * Shell script detection... if the exec_path starts with #! then
431 * we want to exec shell-script-name exec-path, not just exec-path
432 * NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl. We do not
433 * hard-code the path to the shell or perl or whatever: Instead, we
434 * assume it's in the path somewhere (generally, the NT tools
436 * We use OpenFile here because it is capable of searching the Path.
439 exec_handle
= find_file(exec_path
, &file_info
);
442 * If we couldn't open the file, just assume that Windows32 will be able
443 * to find and execute it.
445 if (exec_handle
== (HANDLE
)HFILE_ERROR
) {
449 /* Attempt to read the first line of the file */
450 if (ReadFile( exec_handle
,
451 buf
, sizeof(buf
) - 1, /* leave room for trailing NULL */
452 &bytes_returned
, 0) == FALSE
|| bytes_returned
< 2) {
454 pproc
->last_err
= GetLastError();
455 pproc
->lerrno
= E_IO
;
456 CloseHandle(exec_handle
);
459 if (buf
[0] == '#' && buf
[1] == '!') {
461 * This is a shell script... Change the command line from
462 * exec_path args to shell_name exec_path args
466 /* Make sure buf is NULL terminated */
467 buf
[bytes_returned
] = 0;
469 * Depending on the file system type, etc. the first line
470 * of the shell script may end with newline or newline-carriage-return
471 * Whatever it ends with, cut it off.
473 p
= strchr(buf
, '\n');
476 p
= strchr(buf
, '\r');
481 * Find base name of shell
483 shell_name
= strrchr( buf
, '/');
487 shell_name
= &buf
[2];/* skipping "#!" */
491 CloseHandle(exec_handle
);
497 command_line
= make_command_line( shell_name
, exec_path
, argv
);
499 command_line
= make_command_line( shell_name
, file_info
.szPathName
,
502 if ( command_line
== NULL
) {
504 pproc
->lerrno
= E_NO_MEM
;
509 if (arr2envblk(envp
, &envblk
) ==FALSE
) {
511 pproc
->lerrno
= E_NO_MEM
;
512 free( command_line
);
517 if ((shell_name
) || (file_not_found
)) {
518 exec_path
= 0; /* Search for the program in %Path% */
520 exec_path
= file_info
.szPathName
;
524 * Set up inherited stdin, stdout, stderr for child
526 GetStartupInfo(&startInfo
);
527 startInfo
.dwFlags
= STARTF_USESTDHANDLES
;
528 startInfo
.lpReserved
= 0;
529 startInfo
.cbReserved2
= 0;
530 startInfo
.lpReserved2
= 0;
531 startInfo
.lpTitle
= shell_name
? shell_name
: exec_path
;
532 startInfo
.hStdInput
= (HANDLE
)pproc
->sv_stdin
[1];
533 startInfo
.hStdOutput
= (HANDLE
)pproc
->sv_stdout
[1];
534 startInfo
.hStdError
= (HANDLE
)pproc
->sv_stderr
[1];
537 if (envblk
) free(envblk
);
540 DB (DB_JOBS
, ("CreateProcess(%s,%s,...)\n",
541 exec_path
? exec_path
: "NULL",
542 command_line
? command_line
: "NULL"));
547 0, /* default security attributes for thread */
548 TRUE
, /* inherit handles (e.g. helper pipes, oserv socket) */
551 0, /* default starting directory */
553 &procInfo
) == FALSE
) {
555 pproc
->last_err
= GetLastError();
556 pproc
->lerrno
= E_FORK
;
557 fprintf(stderr
, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
558 exec_path
? exec_path
: "NULL", command_line
);
559 if (envblk
) free(envblk
);
560 free( command_line
);
565 pproc
->pid
= (int)procInfo
.hProcess
;
566 /* Close the thread handle -- we'll just watch the process */
567 CloseHandle(procInfo
.hThread
);
569 /* Close the halves of the pipes we don't need */
570 CloseHandle((HANDLE
)pproc
->sv_stdin
[1]);
571 CloseHandle((HANDLE
)pproc
->sv_stdout
[1]);
572 CloseHandle((HANDLE
)pproc
->sv_stderr
[1]);
573 pproc
->sv_stdin
[1] = 0;
574 pproc
->sv_stdout
[1] = 0;
575 pproc
->sv_stderr
[1] = 0;
577 free( command_line
);
578 if (envblk
) free(envblk
);
586 proc_stdin_thread(sub_process
*pproc
)
590 if (WriteFile( (HANDLE
) pproc
->sv_stdin
[0], pproc
->inp
, pproc
->incnt
,
591 &in_done
, NULL
) == FALSE
)
593 // This if should never be true for anonymous pipes, but gives
594 // us a chance to change I/O mechanisms later
595 if (in_done
< pproc
->incnt
) {
596 pproc
->incnt
-= in_done
;
597 pproc
->inp
+= in_done
;
602 return 0; // for compiler warnings only.. not reached
606 proc_stdout_thread(sub_process
*pproc
)
608 DWORD bufsize
= 1024;
611 pproc
->outp
= malloc(bufsize
);
612 if (pproc
->outp
== NULL
)
617 if (ReadFile( (HANDLE
)pproc
->sv_stdout
[0], &c
, 1, &nread
, NULL
)
619 /* map_windows32_error_to_string(GetLastError());*/
624 if (pproc
->outcnt
+ nread
> bufsize
) {
625 bufsize
+= nread
+ 512;
626 pproc
->outp
= realloc(pproc
->outp
, bufsize
);
627 if (pproc
->outp
== NULL
) {
632 pproc
->outp
[pproc
->outcnt
++] = c
;
638 proc_stderr_thread(sub_process
*pproc
)
640 DWORD bufsize
= 1024;
643 pproc
->errp
= malloc(bufsize
);
644 if (pproc
->errp
== NULL
)
649 if (ReadFile( (HANDLE
)pproc
->sv_stderr
[0], &c
, 1, &nread
, NULL
) == FALSE
) {
650 map_windows32_error_to_string(GetLastError());
655 if (pproc
->errcnt
+ nread
> bufsize
) {
656 bufsize
+= nread
+ 512;
657 pproc
->errp
= realloc(pproc
->errp
, bufsize
);
658 if (pproc
->errp
== NULL
) {
663 pproc
->errp
[pproc
->errcnt
++] = c
;
670 * Purpose: collects output from child process and returns results
676 * Notes/Dependencies:
684 sub_process
*pproc
= (sub_process
*)proc
;
685 bool_t stdin_eof
= FALSE
, stdout_eof
= FALSE
, stderr_eof
= FALSE
;
686 HANDLE childhand
= (HANDLE
) pproc
->pid
;
687 HANDLE tStdin
= NULL
, tStdout
= NULL
, tStderr
= NULL
;
688 unsigned int dwStdin
, dwStdout
, dwStderr
;
693 bool_t child_dead
= FALSE
;
694 BOOL GetExitCodeResult
;
697 * Create stdin thread, if needed
699 pproc
->inp
= stdin_data
;
700 pproc
->incnt
= stdin_data_len
;
703 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
704 pproc
->sv_stdin
[0] = 0;
706 tStdin
= (HANDLE
) _beginthreadex( 0, 1024,
707 (unsigned (__stdcall
*) (void *))proc_stdin_thread
,
710 pproc
->last_err
= GetLastError();
711 pproc
->lerrno
= E_SCALL
;
717 * Assume child will produce stdout and stderr
719 tStdout
= (HANDLE
) _beginthreadex( 0, 1024,
720 (unsigned (__stdcall
*) (void *))proc_stdout_thread
, pproc
, 0,
722 tStderr
= (HANDLE
) _beginthreadex( 0, 1024,
723 (unsigned (__stdcall
*) (void *))proc_stderr_thread
, pproc
, 0,
726 if (tStdout
== 0 || tStderr
== 0) {
728 pproc
->last_err
= GetLastError();
729 pproc
->lerrno
= E_SCALL
;
735 * Wait for all I/O to finish and for the child process to exit
738 while (!stdin_eof
|| !stdout_eof
|| !stderr_eof
|| !child_dead
) {
741 wait_list
[wait_count
++] = tStdin
;
744 wait_list
[wait_count
++] = tStdout
;
747 wait_list
[wait_count
++] = tStderr
;
750 wait_list
[wait_count
++] = childhand
;
753 wait_return
= WaitForMultipleObjects(wait_count
, wait_list
,
754 FALSE
, /* don't wait for all: one ready will do */
755 child_dead
? 1000 :INFINITE
); /* after the child dies, subthreads have
756 one second to collect all remaining output */
758 if (wait_return
== WAIT_FAILED
) {
759 /* map_windows32_error_to_string(GetLastError());*/
760 pproc
->last_err
= GetLastError();
761 pproc
->lerrno
= E_SCALL
;
765 ready_hand
= wait_list
[wait_return
- WAIT_OBJECT_0
];
767 if (ready_hand
== tStdin
) {
768 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
769 pproc
->sv_stdin
[0] = 0;
774 } else if (ready_hand
== tStdout
) {
776 CloseHandle((HANDLE
)pproc
->sv_stdout
[0]);
777 pproc
->sv_stdout
[0] = 0;
778 CloseHandle(tStdout
);
782 } else if (ready_hand
== tStderr
) {
784 CloseHandle((HANDLE
)pproc
->sv_stderr
[0]);
785 pproc
->sv_stderr
[0] = 0;
786 CloseHandle(tStderr
);
790 } else if (ready_hand
== childhand
) {
793 GetExitCodeResult
= GetExitCodeProcess(childhand
, &ierr
);
794 if (ierr
== CONTROL_C_EXIT
) {
795 pproc
->signal
= SIGINT
;
797 pproc
->exit_code
= ierr
;
799 if (GetExitCodeResult
== FALSE
) {
800 pproc
->last_err
= GetLastError();
801 pproc
->lerrno
= E_SCALL
;
808 /* ?? Got back a handle we didn't query ?? */
810 pproc
->lerrno
= E_FAIL
;
819 CloseHandle(tStdout
);
821 CloseHandle(tStderr
);
831 * Purpose: collects output from child process and returns results
837 * Notes/Dependencies:
846 BOOL GetExitCodeResult
;
850 pproc
= process_wait_for_any_private();
852 pproc
= (sub_process
*)proc
;
854 /* some sort of internal error */
858 childhand
= (HANDLE
) pproc
->pid
;
861 * This function is poorly named, and could also be used just to wait
862 * for child death if you're doing your own pipe I/O. If that is
863 * the case, close the pipe handles here.
865 if (pproc
->sv_stdin
[0]) {
866 CloseHandle((HANDLE
)pproc
->sv_stdin
[0]);
867 pproc
->sv_stdin
[0] = 0;
869 if (pproc
->sv_stdout
[0]) {
870 CloseHandle((HANDLE
)pproc
->sv_stdout
[0]);
871 pproc
->sv_stdout
[0] = 0;
873 if (pproc
->sv_stderr
[0]) {
874 CloseHandle((HANDLE
)pproc
->sv_stderr
[0]);
875 pproc
->sv_stderr
[0] = 0;
879 * Wait for the child process to exit
882 wait_return
= WaitForSingleObject(childhand
, INFINITE
);
884 if (wait_return
!= WAIT_OBJECT_0
) {
885 /* map_windows32_error_to_string(GetLastError());*/
886 pproc
->last_err
= GetLastError();
887 pproc
->lerrno
= E_SCALL
;
891 GetExitCodeResult
= GetExitCodeProcess(childhand
, &ierr
);
892 if (ierr
== CONTROL_C_EXIT
) {
893 pproc
->signal
= SIGINT
;
895 pproc
->exit_code
= ierr
;
897 if (GetExitCodeResult
== FALSE
) {
898 pproc
->last_err
= GetLastError();
899 pproc
->lerrno
= E_SCALL
;
911 * Description: Clean up any leftover handles, etc. It is up to the
912 * caller to manage and free the input, ouput, and stderr buffers.
918 sub_process
*pproc
= (sub_process
*)proc
;
921 if (pproc
->using_pipes
) {
922 for (i
= 0; i
<= 1; i
++) {
923 if ((HANDLE
)pproc
->sv_stdin
[i
])
924 CloseHandle((HANDLE
)pproc
->sv_stdin
[i
]);
925 if ((HANDLE
)pproc
->sv_stdout
[i
])
926 CloseHandle((HANDLE
)pproc
->sv_stdout
[i
]);
927 if ((HANDLE
)pproc
->sv_stderr
[i
])
928 CloseHandle((HANDLE
)pproc
->sv_stderr
[i
]);
931 if ((HANDLE
)pproc
->pid
)
932 CloseHandle((HANDLE
)pproc
->pid
);
940 * Create a command line buffer to pass to CreateProcess
942 * Returns: the buffer or NULL for failure
943 * Shell case: sh_name a:/full/path/to/script argv[1] argv[2] ...
944 * Otherwise: argv[0] argv[1] argv[2] ...
946 * Notes/Dependencies:
947 * CreateProcess does not take an argv, so this command creates a
948 * command line for the executable.
952 make_command_line( char *shell_name
, char *full_exec_path
, char **argv
)
956 int* enclose_in_quotes
= NULL
;
957 int* enclose_in_quotes_i
;
958 unsigned int bytes_required
= 0;
960 char* command_line_i
;
961 int cygwin_mode
= 0; /* HAVE_CYGWIN_SHELL */
962 int have_sh
= 0; /* HAVE_CYGWIN_SHELL */
964 #ifdef HAVE_CYGWIN_SHELL
965 have_sh
= (shell_name
!= NULL
|| strstr(full_exec_path
, "sh.exe"));
969 if (shell_name
&& full_exec_path
) {
971 = strlen(shell_name
) + 1 + strlen(full_exec_path
);
973 * Skip argv[0] if any, when shell_name is given.
977 * Add one for the intervening space.
979 if (*argv
) bytes_required
++;
983 while (*(argvi
++)) argc
++;
986 enclose_in_quotes
= (int*) calloc(1, argc
* sizeof(int));
988 if (!enclose_in_quotes
) {
993 /* We have to make one pass through each argv[i] to see if we need
994 * to enclose it in ", so we might as well figure out how much
995 * memory we'll need on the same pass.
999 enclose_in_quotes_i
= enclose_in_quotes
;
1002 unsigned int backslash_count
= 0;
1005 * We have to enclose empty arguments in ".
1007 if (!(*p
)) *enclose_in_quotes_i
= 1;
1013 * We have to insert a backslash for each "
1014 * and each \ that precedes the ".
1016 bytes_required
+= (backslash_count
+ 1);
1017 backslash_count
= 0;
1020 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1026 * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
1027 * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
1028 * that argv in always equals argv out. This was removed. Say you have
1029 * such a program named glob.exe. You enter
1031 * at the sh command prompt. Obviously the intent is to make glob do the
1032 * wildcarding instead of sh. If we set *enclose_in_quotes_i for '*' or '?',
1033 * then the command line that glob would see would be
1035 * and the _setargv in SETARGV.OBJ would _not_ expand the *.
1039 *enclose_in_quotes_i
= 1;
1043 backslash_count
= 0;
1048 * Add one for each character in argv[i].
1055 if (*enclose_in_quotes_i
) {
1057 * Add one for each enclosing ",
1058 * and one for each \ that precedes the
1061 bytes_required
+= (backslash_count
+ 2);
1065 * Add one for the intervening space.
1067 if (*(++argvi
)) bytes_required
++;
1068 enclose_in_quotes_i
++;
1072 * Add one for the terminating NULL.
1076 command_line
= (char*) malloc(bytes_required
);
1078 if (!command_line
) {
1079 if (enclose_in_quotes
) free(enclose_in_quotes
);
1083 command_line_i
= command_line
;
1085 if (shell_name
&& full_exec_path
) {
1086 while(*shell_name
) {
1087 *(command_line_i
++) = *(shell_name
++);
1090 *(command_line_i
++) = ' ';
1092 while(*full_exec_path
) {
1093 *(command_line_i
++) = *(full_exec_path
++);
1097 *(command_line_i
++) = ' ';
1102 enclose_in_quotes_i
= enclose_in_quotes
;
1106 unsigned int backslash_count
= 0;
1108 if (*enclose_in_quotes_i
) {
1109 *(command_line_i
++) = '\"';
1114 if (cygwin_mode
&& have_sh
) { /* HAVE_CYGWIN_SHELL */
1115 /* instead of a \", cygwin likes "" */
1116 *(command_line_i
++) = '\"';
1120 * We have to insert a backslash for the "
1121 * and each \ that precedes the ".
1125 while(backslash_count
) {
1126 *(command_line_i
++) = '\\';
1130 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1131 } else if (*p
== '\\') {
1134 backslash_count
= 0;
1139 * Copy the character.
1141 *(command_line_i
++) = *(p
++);
1144 if (*enclose_in_quotes_i
) {
1145 #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
1147 * Add one \ for each \ that precedes the
1150 while(backslash_count
--) {
1151 *(command_line_i
++) = '\\';
1154 *(command_line_i
++) = '\"';
1158 * Append an intervening space.
1161 *(command_line_i
++) = ' ';
1164 enclose_in_quotes_i
++;
1168 * Append the terminating NULL.
1170 *command_line_i
= '\0';
1172 if (enclose_in_quotes
) free(enclose_in_quotes
);
1173 return command_line
;
1177 * Description: Given an argv and optional envp, launch the process
1178 * using the default stdin, stdout, and stderr handles.
1179 * Also, register process so that process_wait_for_any_private()
1180 * can be used via process_file_io(NULL) or
1181 * process_wait_for_any().
1185 * Notes/Dependencies:
1197 if (proc_index
>= MAXIMUM_WAIT_OBJECTS
) {
1198 DB (DB_JOBS
, ("process_easy: All process slots used up\n"));
1199 return INVALID_HANDLE_VALUE
;
1201 if (DuplicateHandle(GetCurrentProcess(),
1202 GetStdHandle(STD_INPUT_HANDLE
),
1203 GetCurrentProcess(),
1207 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1209 "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
1211 return INVALID_HANDLE_VALUE
;
1213 if (DuplicateHandle(GetCurrentProcess(),
1214 GetStdHandle(STD_OUTPUT_HANDLE
),
1215 GetCurrentProcess(),
1219 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1221 "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
1223 return INVALID_HANDLE_VALUE
;
1225 if (DuplicateHandle(GetCurrentProcess(),
1226 GetStdHandle(STD_ERROR_HANDLE
),
1227 GetCurrentProcess(),
1231 DUPLICATE_SAME_ACCESS
) == FALSE
) {
1233 "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
1235 return INVALID_HANDLE_VALUE
;
1238 hProcess
= process_init_fd(hIn
, hOut
, hErr
);
1240 if (process_begin(hProcess
, argv
, envp
, argv
[0], NULL
)) {
1241 fake_exits_pending
++;
1242 /* process_begin() failed: make a note of that. */
1243 if (!((sub_process
*) hProcess
)->last_err
)
1244 ((sub_process
*) hProcess
)->last_err
= -1;
1245 ((sub_process
*) hProcess
)->exit_code
= process_last_err(hProcess
);
1247 /* close up unused handles */
1253 process_register(hProcess
);