[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