diff options
author | Eli Zaretskii <eliz@gnu.org> | 2012-01-28 16:50:21 +0000 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2012-01-28 16:50:21 +0000 |
commit | eb4f9669716367912244182dd0eb788759f800ec (patch) | |
tree | f0459dbdc7a17303defe24423f921f1d1bc8e599 /function.c | |
parent | 715a11735f910d69b141c3b851ca1a806907f43f (diff) | |
download | gunmake-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.c | 73 |
1 files changed, 54 insertions, 19 deletions
@@ -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); |