mirror of
https://salsa.debian.org/srivasta/make-dfsg.git
synced 2025-01-30 16:41:44 +00:00
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.
This commit is contained in:
parent
715a11735f
commit
eb4f966971
3 changed files with 189 additions and 71 deletions
22
ChangeLog
22
ChangeLog
|
@ -1,3 +1,25 @@
|
||||||
|
2012-01-28 Eli Zaretskii <eliz@gnu.org>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2012-01-25 Eli Zaretskii <eliz@gnu.org>
|
2012-01-25 Eli Zaretskii <eliz@gnu.org>
|
||||||
|
|
||||||
* function.c (define_new_function): Fix format strings in calls to
|
* function.c (define_new_function): Fix format strings in calls to
|
||||||
|
|
73
function.c
73
function.c
|
@ -1434,37 +1434,70 @@ void
|
||||||
windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp)
|
windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp)
|
||||||
{
|
{
|
||||||
SECURITY_ATTRIBUTES saAttr;
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
HANDLE hIn;
|
HANDLE hIn = INVALID_HANDLE_VALUE;
|
||||||
HANDLE hErr;
|
HANDLE hErr = INVALID_HANDLE_VALUE;
|
||||||
HANDLE hChildOutRd;
|
HANDLE hChildOutRd;
|
||||||
HANDLE hChildOutWr;
|
HANDLE hChildOutWr;
|
||||||
HANDLE hProcess;
|
HANDLE hProcess, tmpIn, tmpErr;
|
||||||
|
DWORD e;
|
||||||
|
|
||||||
saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
|
saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
|
||||||
saAttr.bInheritHandle = TRUE;
|
saAttr.bInheritHandle = TRUE;
|
||||||
saAttr.lpSecurityDescriptor = NULL;
|
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(),
|
if (DuplicateHandle (GetCurrentProcess(),
|
||||||
GetStdHandle(STD_INPUT_HANDLE),
|
tmpIn,
|
||||||
GetCurrentProcess(),
|
GetCurrentProcess(),
|
||||||
&hIn,
|
&hIn,
|
||||||
0,
|
0,
|
||||||
TRUE,
|
TRUE,
|
||||||
DUPLICATE_SAME_ACCESS) == FALSE) {
|
DUPLICATE_SAME_ACCESS) == FALSE) {
|
||||||
fatal (NILF, _("windows32_openpipe(): DuplicateHandle(In) failed (e=%ld)\n"),
|
if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
|
||||||
GetLastError());
|
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(),
|
if (DuplicateHandle(GetCurrentProcess(),
|
||||||
GetStdHandle(STD_ERROR_HANDLE),
|
tmpErr,
|
||||||
GetCurrentProcess(),
|
GetCurrentProcess(),
|
||||||
&hErr,
|
&hErr,
|
||||||
0,
|
0,
|
||||||
TRUE,
|
TRUE,
|
||||||
DUPLICATE_SAME_ACCESS) == FALSE) {
|
DUPLICATE_SAME_ACCESS) == FALSE) {
|
||||||
fatal (NILF, _("windows32_open_pipe(): DuplicateHandle(Err) failed (e=%ld)\n"),
|
if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
|
||||||
GetLastError());
|
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))
|
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)) {
|
if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
|
||||||
/* register process for wait */
|
/* register process for wait */
|
||||||
process_register(hProcess);
|
process_register(hProcess);
|
||||||
|
|
||||||
/* set the pid for returning to caller */
|
/* set the pid for returning to caller */
|
||||||
*pid_p = (pid_t) hProcess;
|
*pid_p = (pid_t) hProcess;
|
||||||
|
|
||||||
/* set up to read data from child */
|
/* set up to read data from child */
|
||||||
pipedes[0] = _open_osfhandle((intptr_t) hChildOutRd, O_RDONLY);
|
pipedes[0] = _open_osfhandle((intptr_t) hChildOutRd, O_RDONLY);
|
||||||
|
|
||||||
/* this will be closed almost right away */
|
/* this will be closed almost right away */
|
||||||
pipedes[1] = _open_osfhandle((intptr_t) hChildOutWr, O_APPEND);
|
pipedes[1] = _open_osfhandle((intptr_t) hChildOutWr, O_APPEND);
|
||||||
} else {
|
} else {
|
||||||
/* reap/cleanup the failed process */
|
/* reap/cleanup the failed process */
|
||||||
process_cleanup(hProcess);
|
process_cleanup(hProcess);
|
||||||
|
|
||||||
/* close handles which were duplicated, they weren't used */
|
/* close handles which were duplicated, they weren't used */
|
||||||
CloseHandle(hIn);
|
if (hIn != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(hErr);
|
CloseHandle(hIn);
|
||||||
|
if (hErr != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(hErr);
|
||||||
|
|
||||||
/* close pipe handles, they won't be used */
|
/* close pipe handles, they won't be used */
|
||||||
CloseHandle(hChildOutRd);
|
CloseHandle(hChildOutRd);
|
||||||
|
|
|
@ -462,17 +462,19 @@ process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
|
||||||
sub_process *pproc;
|
sub_process *pproc;
|
||||||
|
|
||||||
pproc = malloc(sizeof(*pproc));
|
pproc = malloc(sizeof(*pproc));
|
||||||
memset(pproc, 0, sizeof(*pproc));
|
if (pproc) {
|
||||||
|
memset(pproc, 0, sizeof(*pproc));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Just pass the provided file handles to the 'child side' of the
|
* Just pass the provided file handles to the 'child
|
||||||
* pipe, bypassing pipes altogether.
|
* side' of the pipe, bypassing pipes altogether.
|
||||||
*/
|
*/
|
||||||
pproc->sv_stdin[1] = (intptr_t) stdinh;
|
pproc->sv_stdin[1] = (intptr_t) stdinh;
|
||||||
pproc->sv_stdout[1] = (intptr_t) stdouth;
|
pproc->sv_stdout[1] = (intptr_t) stdouth;
|
||||||
pproc->sv_stderr[1] = (intptr_t) stderrh;
|
pproc->sv_stderr[1] = (intptr_t) stderrh;
|
||||||
|
|
||||||
pproc->last_err = pproc->lerrno = 0;
|
pproc->last_err = pproc->lerrno = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return((HANDLE)pproc);
|
return((HANDLE)pproc);
|
||||||
}
|
}
|
||||||
|
@ -711,9 +713,12 @@ process_begin(
|
||||||
CloseHandle(procInfo.hThread);
|
CloseHandle(procInfo.hThread);
|
||||||
|
|
||||||
/* Close the halves of the pipes we don't need */
|
/* Close the halves of the pipes we don't need */
|
||||||
CloseHandle((HANDLE)pproc->sv_stdin[1]);
|
if ((HANDLE)pproc->sv_stdin[1] != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle((HANDLE)pproc->sv_stdout[1]);
|
CloseHandle((HANDLE)pproc->sv_stdin[1]);
|
||||||
CloseHandle((HANDLE)pproc->sv_stderr[1]);
|
if ((HANDLE)pproc->sv_stdout[1] != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle((HANDLE)pproc->sv_stdout[1]);
|
||||||
|
if ((HANDLE)pproc->sv_stderr[1] != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle((HANDLE)pproc->sv_stderr[1]);
|
||||||
pproc->sv_stdin[1] = 0;
|
pproc->sv_stdin[1] = 0;
|
||||||
pproc->sv_stdout[1] = 0;
|
pproc->sv_stdout[1] = 0;
|
||||||
pproc->sv_stderr[1] = 0;
|
pproc->sv_stderr[1] = 0;
|
||||||
|
@ -1064,11 +1069,14 @@ process_cleanup(
|
||||||
|
|
||||||
if (pproc->using_pipes) {
|
if (pproc->using_pipes) {
|
||||||
for (i= 0; i <= 1; i++) {
|
for (i= 0; i <= 1; i++) {
|
||||||
if ((HANDLE)pproc->sv_stdin[i])
|
if ((HANDLE)pproc->sv_stdin[i]
|
||||||
|
&& (HANDLE)pproc->sv_stdin[i] != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle((HANDLE)pproc->sv_stdin[i]);
|
CloseHandle((HANDLE)pproc->sv_stdin[i]);
|
||||||
if ((HANDLE)pproc->sv_stdout[i])
|
if ((HANDLE)pproc->sv_stdout[i]
|
||||||
|
&& (HANDLE)pproc->sv_stdout[i] != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle((HANDLE)pproc->sv_stdout[i]);
|
CloseHandle((HANDLE)pproc->sv_stdout[i]);
|
||||||
if ((HANDLE)pproc->sv_stderr[i])
|
if ((HANDLE)pproc->sv_stderr[i]
|
||||||
|
&& (HANDLE)pproc->sv_stderr[i] != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle((HANDLE)pproc->sv_stderr[i]);
|
CloseHandle((HANDLE)pproc->sv_stderr[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1333,50 +1341,100 @@ process_easy(
|
||||||
char **argv,
|
char **argv,
|
||||||
char **envp)
|
char **envp)
|
||||||
{
|
{
|
||||||
HANDLE hIn;
|
HANDLE hIn = INVALID_HANDLE_VALUE;
|
||||||
HANDLE hOut;
|
HANDLE hOut = INVALID_HANDLE_VALUE;
|
||||||
HANDLE hErr;
|
HANDLE hErr = INVALID_HANDLE_VALUE;
|
||||||
HANDLE hProcess;
|
HANDLE hProcess, tmpIn, tmpOut, tmpErr;
|
||||||
|
DWORD e;
|
||||||
|
|
||||||
if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
|
if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
|
||||||
DB (DB_JOBS, ("process_easy: All process slots used up\n"));
|
DB (DB_JOBS, ("process_easy: All process slots used up\n"));
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
/* 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
|
||||||
|
CreateProcess as the corresponding handle to inherit. */
|
||||||
|
tmpIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
if (DuplicateHandle(GetCurrentProcess(),
|
if (DuplicateHandle(GetCurrentProcess(),
|
||||||
GetStdHandle(STD_INPUT_HANDLE),
|
tmpIn,
|
||||||
GetCurrentProcess(),
|
GetCurrentProcess(),
|
||||||
&hIn,
|
&hIn,
|
||||||
0,
|
0,
|
||||||
TRUE,
|
TRUE,
|
||||||
DUPLICATE_SAME_ACCESS) == FALSE) {
|
DUPLICATE_SAME_ACCESS) == FALSE) {
|
||||||
fprintf(stderr,
|
if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
|
||||||
"process_easy: DuplicateHandle(In) failed (e=%ld)\n",
|
tmpIn = CreateFile("NUL", GENERIC_READ,
|
||||||
GetLastError());
|
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||||
return INVALID_HANDLE_VALUE;
|
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) {
|
||||||
|
fprintf(stderr, "process_easy: DuplicateHandle(In) failed (e=%ld)\n", e);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
tmpOut = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||||
if (DuplicateHandle(GetCurrentProcess(),
|
if (DuplicateHandle(GetCurrentProcess(),
|
||||||
GetStdHandle(STD_OUTPUT_HANDLE),
|
tmpOut,
|
||||||
GetCurrentProcess(),
|
GetCurrentProcess(),
|
||||||
&hOut,
|
&hOut,
|
||||||
0,
|
0,
|
||||||
TRUE,
|
TRUE,
|
||||||
DUPLICATE_SAME_ACCESS) == FALSE) {
|
DUPLICATE_SAME_ACCESS) == FALSE) {
|
||||||
fprintf(stderr,
|
if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
|
||||||
"process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
|
tmpOut = CreateFile("NUL", GENERIC_WRITE,
|
||||||
GetLastError());
|
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||||
return INVALID_HANDLE_VALUE;
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (tmpOut != INVALID_HANDLE_VALUE
|
||||||
|
&& DuplicateHandle(GetCurrentProcess(),
|
||||||
|
tmpOut,
|
||||||
|
GetCurrentProcess(),
|
||||||
|
&hOut,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
DUPLICATE_SAME_ACCESS) == FALSE)
|
||||||
|
CloseHandle(tmpOut);
|
||||||
|
}
|
||||||
|
if (hOut == INVALID_HANDLE_VALUE) {
|
||||||
|
fprintf(stderr, "process_easy: DuplicateHandle(Out) failed (e=%ld)\n", e);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
tmpErr = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
if (DuplicateHandle(GetCurrentProcess(),
|
if (DuplicateHandle(GetCurrentProcess(),
|
||||||
GetStdHandle(STD_ERROR_HANDLE),
|
tmpErr,
|
||||||
GetCurrentProcess(),
|
GetCurrentProcess(),
|
||||||
&hErr,
|
&hErr,
|
||||||
0,
|
0,
|
||||||
TRUE,
|
TRUE,
|
||||||
DUPLICATE_SAME_ACCESS) == FALSE) {
|
DUPLICATE_SAME_ACCESS) == FALSE) {
|
||||||
fprintf(stderr,
|
if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
|
||||||
"process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
|
tmpErr = CreateFile("NUL", GENERIC_WRITE,
|
||||||
GetLastError());
|
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||||
return INVALID_HANDLE_VALUE;
|
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) {
|
||||||
|
fprintf(stderr, "process_easy: DuplicateHandle(Err) failed (e=%ld)\n", e);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hProcess = process_init_fd(hIn, hOut, hErr);
|
hProcess = process_init_fd(hIn, hOut, hErr);
|
||||||
|
@ -1389,9 +1447,12 @@ process_easy(
|
||||||
((sub_process*) hProcess)->exit_code = process_last_err(hProcess);
|
((sub_process*) hProcess)->exit_code = process_last_err(hProcess);
|
||||||
|
|
||||||
/* close up unused handles */
|
/* close up unused handles */
|
||||||
CloseHandle(hIn);
|
if (hIn != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(hOut);
|
CloseHandle(hIn);
|
||||||
CloseHandle(hErr);
|
if (hOut != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(hOut);
|
||||||
|
if (hErr != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(hErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
process_register(hProcess);
|
process_register(hProcess);
|
||||||
|
|
Loading…
Reference in a new issue