Commit d501f70c authored by Tilman Blumhagen's avatar Tilman Blumhagen
Browse files

#110, On Windows ignore ERROR_ACCESS_DENIED for TerminateProcess() if the process did terminate

To my knowledge this behavior is not officially documented. But it seems
multiple people discovered ERROR_ACCESS_DENIED when trying to terminate
a process that did already die on its own. For example libuv has a
workaround for this.
parent c4fa0b81
......@@ -786,6 +786,25 @@ int
terminateProcess (ProcHandle handle)
{
if (!TerminateProcess ((HANDLE) handle, 1)) {
DWORD e = GetLastError();
DWORD exitCode;
/*
This is a crude workaround that is taken from libuv. For some reason
TerminateProcess() can fail with ERROR_ACCESS_DENIED if the process
already terminated. This situation can be detected by using
GetExitCodeProcess() to check if the exit code is availble. Unfortunately
this function succeeds and gives exit code 259 (STILL_ACTIVE) if the
process is still running. So there is no way to ditinguish a process
that exited with 259 and a process that did not exit because we had
insufficient access to terminate it.
One would expect WaitForSingleObject() to be the solid solution. But this
function does return WAIT_TIMEOUT in that situation. Even if called
after GetExitCodeProcess().
*/
if (e == ERROR_ACCESS_DENIED && GetExitCodeProcess((HANDLE) handle, &exitCode) && exitCode != STILL_ACTIVE)
return 0;
SetLastError(e);
maperrno();
return -1;
}
......
......@@ -2,6 +2,9 @@
## Unreleased changes
* Bug fix: On Windows ignore ERROR_ACCESS_DENIED for TerminateProcess() if the process did terminate
[#110](https://github.com/haskell/process/issues/110)
## 1.6.4.0 *July 2018*
* Bug fix: Don't leak pipes on failure
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment