[Pkg-privacy-commits] [pyptlib] 74/136: testing whether a process exists in a cross-platform way takes 40 lines, sigh

Ximin Luo infinity0 at moszumanska.debian.org
Sat Aug 22 13:25:11 UTC 2015


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository pyptlib.

commit c0977489c1630efc6f682b6a9f4fb8957c67c4db
Author: Ximin Luo <infinity0 at gmx.com>
Date:   Wed Aug 7 00:59:49 2013 +0100

    testing whether a process exists in a cross-platform way takes 40 lines, sigh
---
 pyptlib/test/test_util_subproc.py |  7 +-----
 pyptlib/util/subproc.py           | 50 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/pyptlib/test/test_util_subproc.py b/pyptlib/test/test_util_subproc.py
index f468c1f..421270f 100644
--- a/pyptlib/test/test_util_subproc.py
+++ b/pyptlib/test/test_util_subproc.py
@@ -4,7 +4,7 @@ import signal
 import subprocess
 import time
 
-from pyptlib.util.subproc import auto_killall, create_sink, Popen, SINK
+from pyptlib.util.subproc import auto_killall, create_sink, proc_is_alive, Popen, SINK
 from subprocess import PIPE
 
 # We ought to run auto_killall(), instead of manually calling proc.terminate()
@@ -14,11 +14,6 @@ def proc_wait(proc, wait_s):
     time.sleep(wait_s)
     proc.poll() # otherwise it doesn't exit properly
 
-def proc_is_alive(pid):
-    r = subprocess.call(("ps -p %s" % pid).split(), stdout=create_sink())
-    return True if r == 0 else False
-
-
 class SubprocTest(unittest.TestCase):
 
     def name(self):
diff --git a/pyptlib/util/subproc.py b/pyptlib/util/subproc.py
index 36d1a32..24522fa 100644
--- a/pyptlib/util/subproc.py
+++ b/pyptlib/util/subproc.py
@@ -9,8 +9,11 @@ import inspect
 import os
 import signal
 import subprocess
+import sys
 import time
 
+mswindows = (sys.platform == "win32")
+
 _CHILD_PROCS = []
 # TODO(infinity0): add functionality to detect when any child dies, and
 # offer different response strategies for them (e.g. restart the child? or die
@@ -47,6 +50,52 @@ class Popen(subprocess.Popen):
 def create_sink():
     return open(os.devnull, "w", 0)
 
+
+if mswindows:
+    # from http://www.madebuild.org/blog/?p=30
+    from ctypes import byref, windll
+    from ctypes.wintypes import DWORD
+
+    # GetExitCodeProcess uses a special exit code to indicate that the process is
+    # still running.
+    _STILL_ACTIVE = 259
+
+    def proc_is_alive(pid):
+        """Check if a pid is still running."""
+
+        handle = windll.kernel32.OpenProcess(1, 0, pid)
+        if handle == 0:
+            return False
+
+        # If the process exited recently, a pid may still exist for the handle.
+        # So, check if we can get the exit code.
+        exit_code = DWORD()
+        is_running = (
+            windll.kernel32.GetExitCodeProcess(handle, byref(exit_code)) == 0)
+        windll.kernel32.CloseHandle(handle)
+
+        # See if we couldn't get the exit code or the exit code indicates that the
+        # process is still running.
+        return is_running or exit_code.value == _STILL_ACTIVE
+
+else:
+    # adapted from http://stackoverflow.com/questions/568271/check-if-pid-is-not-in-use-in-python
+    import errno
+
+    def proc_is_alive(pid):
+        """Check if a pid is still running."""
+        try:
+            os.kill(pid, 0)
+        except OSError as e:
+            if e.errno == errno.EPERM:
+                return True
+            if e.errno == errno.ESRCH:
+                return False
+            raise # something else went wrong
+        else:
+            return True
+
+
 _SIGINT_RUN = {}
 def trap_sigint(handler, ignoreNum=0):
     """Register a handler for an INT signal.
@@ -87,6 +136,7 @@ def _run_sigint_handlers(signum=0, sframe=None):
     if exc_info is not None:
         raise exc_info[0], exc_info[1], exc_info[2]
 
+
 _isTerminating = False
 def killall(wait_s=16):
     """Attempt to gracefully terminate all child processes.

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/pyptlib.git



More information about the Pkg-privacy-commits mailing list