#110, On Windows ignore ERROR_ACCESS_DENIED for TerminateProcess() if the process...
authorTilman Blumhagen <tilman.blumhagen@googlemail.com>
Thu, 16 Nov 2017 18:00:22 +0000 (19:00 +0100)
committerTilman Blumhagen <tilman.blumhagen@googlemail.com>
Sun, 9 Dec 2018 12:35:31 +0000 (13:35 +0100)
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.

cbits/runProcess.c
changelog.md

index 16ef4fe..c621158 100644 (file)
@@ -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;
     }
index 5ab0950..836e975 100644 (file)
@@ -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