summaryrefslogtreecommitdiff
path: root/function.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2012-01-28 16:50:21 +0000
committerEli Zaretskii <eliz@gnu.org>2012-01-28 16:50:21 +0000
commiteb4f9669716367912244182dd0eb788759f800ec (patch)
treef0459dbdc7a17303defe24423f921f1d1bc8e599 /function.c
parent715a11735f910d69b141c3b851ca1a806907f43f (diff)
downloadgunmake-eb4f9669716367912244182dd0eb788759f800ec.tar.gz
Fix failures on MS-Windows when Make's standard handles are invalid.
This can happen when Make is invoked from a GUI application. * w32/subproc/sub_proc.c (process_init_fd): Don't dereference pproc if it is a NULL pointer. (process_begin, process_cleanup): Don't try to close pipe handles whose value is INVALID_HANDLE_VALUE. (process_easy): Initialize hIn, hOut, and hErr to INVALID_HANDLE_VALUE. If DuplicateHandle fails with ERROR_INVALID_HANDLE, duplicate a handle for the null device instead of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE or STD_ERROR_HANDLE. Don't try to close pipe handles whose value is INVALID_HANDLE_VALUE. * function.c (windows32_openpipe): Initialize hIn and hErr to INVALID_HANDLE_VALUE. If DuplicateHandle fails with ERROR_INVALID_HANDLE, duplicate a handle for the null device instead of STD_INPUT_HANDLE or STD_ERROR_HANDLE. Fix indentation. Don't try to close handles whose value is INVALID_HANDLE_VALUE.
Diffstat (limited to 'function.c')
-rw-r--r--function.c73
1 files changed, 54 insertions, 19 deletions
diff --git a/function.c b/function.c
index 52235db..29b106f 100644
--- a/function.c
+++ b/function.c
@@ -1434,37 +1434,70 @@ void
windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp)
{
SECURITY_ATTRIBUTES saAttr;
- HANDLE hIn;
- HANDLE hErr;
+ HANDLE hIn = INVALID_HANDLE_VALUE;
+ HANDLE hErr = INVALID_HANDLE_VALUE;
HANDLE hChildOutRd;
HANDLE hChildOutWr;
- HANDLE hProcess;
-
+ HANDLE hProcess, tmpIn, tmpErr;
+ DWORD e;
saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
+ /* Standard handles returned by GetStdHandle can be NULL or
+ INVALID_HANDLE_VALUE if the parent process closed them. If that
+ happens, we open the null device and pass its handle to
+ process_begin below as the corresponding handle to inherit. */
+ tmpIn = GetStdHandle(STD_INPUT_HANDLE);
if (DuplicateHandle (GetCurrentProcess(),
- GetStdHandle(STD_INPUT_HANDLE),
+ tmpIn,
GetCurrentProcess(),
&hIn,
0,
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) {
- fatal (NILF, _("windows32_openpipe(): DuplicateHandle(In) failed (e=%ld)\n"),
- GetLastError());
-
+ if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
+ tmpIn = CreateFile("NUL", GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (tmpIn != INVALID_HANDLE_VALUE
+ && DuplicateHandle(GetCurrentProcess(),
+ tmpIn,
+ GetCurrentProcess(),
+ &hIn,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS) == FALSE)
+ CloseHandle(tmpIn);
+ }
+ if (hIn == INVALID_HANDLE_VALUE)
+ fatal (NILF, _("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
}
+ tmpErr = GetStdHandle(STD_ERROR_HANDLE);
if (DuplicateHandle(GetCurrentProcess(),
- GetStdHandle(STD_ERROR_HANDLE),
+ tmpErr,
GetCurrentProcess(),
&hErr,
0,
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) {
- fatal (NILF, _("windows32_open_pipe(): DuplicateHandle(Err) failed (e=%ld)\n"),
- GetLastError());
+ if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
+ tmpErr = CreateFile("NUL", GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (tmpErr != INVALID_HANDLE_VALUE
+ && DuplicateHandle(GetCurrentProcess(),
+ tmpErr,
+ GetCurrentProcess(),
+ &hErr,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS) == FALSE)
+ CloseHandle(tmpErr);
+ }
+ if (hErr == INVALID_HANDLE_VALUE)
+ fatal (NILF, _("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
}
if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
@@ -1483,23 +1516,25 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
/* register process for wait */
- process_register(hProcess);
+ process_register(hProcess);
/* set the pid for returning to caller */
- *pid_p = (pid_t) hProcess;
+ *pid_p = (pid_t) hProcess;
- /* set up to read data from child */
- pipedes[0] = _open_osfhandle((intptr_t) hChildOutRd, O_RDONLY);
+ /* set up to read data from child */
+ pipedes[0] = _open_osfhandle((intptr_t) hChildOutRd, O_RDONLY);
- /* this will be closed almost right away */
- pipedes[1] = _open_osfhandle((intptr_t) hChildOutWr, O_APPEND);
+ /* this will be closed almost right away */
+ pipedes[1] = _open_osfhandle((intptr_t) hChildOutWr, O_APPEND);
} else {
/* reap/cleanup the failed process */
process_cleanup(hProcess);
/* close handles which were duplicated, they weren't used */
- CloseHandle(hIn);
- CloseHandle(hErr);
+ if (hIn != INVALID_HANDLE_VALUE)
+ CloseHandle(hIn);
+ if (hErr != INVALID_HANDLE_VALUE)
+ CloseHandle(hErr);
/* close pipe handles, they won't be used */
CloseHandle(hChildOutRd);