Plain is headed towards 1.0! Subscribe for development updates →

 1"""
 2Compatibility layer and utilities, mostly for proper Windows and Python 3
 3support.
 4"""
 5
 6import errno
 7import os
 8import signal
 9import sys
10
11# This works for both 32 and 64 bit Windows
12ON_WINDOWS = "win32" in str(sys.platform).lower()
13
14if ON_WINDOWS:
15    import ctypes
16
17
18class ProcessManager:
19    if ON_WINDOWS:
20
21        def terminate(self, pid):
22            # The first argument to OpenProcess represents the desired access
23            # to the process. 1 represents the PROCESS_TERMINATE access right.
24            handle = ctypes.windll.kernel32.OpenProcess(1, False, pid)
25            ctypes.windll.kernel32.TerminateProcess(handle, -1)
26            ctypes.windll.kernel32.CloseHandle(handle)
27    else:
28
29        def terminate(self, pid):
30            try:
31                os.killpg(pid, signal.SIGTERM)
32            except OSError as e:
33                if e.errno not in [errno.EPERM, errno.ESRCH]:
34                    raise
35
36    if ON_WINDOWS:
37
38        def kill(self, pid):
39            # There's no SIGKILL on Win32...
40            self.terminate(pid)
41    else:
42
43        def kill(self, pid):
44            try:
45                os.killpg(pid, signal.SIGKILL)
46            except OSError as e:
47                if e.errno not in [errno.EPERM, errno.ESRCH]:
48                    raise