1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
"""
Support routines for subprocess module.
Currently, this extension module is only required when using the
subprocess module on Windows.
"""
# Declare external Win32 functions
import ctypes
_kernel32 = ctypes.WinDLL('kernel32')
_CloseHandle = _kernel32.CloseHandle
_CloseHandle.argtypes = [ctypes.c_int]
_CloseHandle.restype = ctypes.c_int
_CreatePipe = _kernel32.CreatePipe
_CreatePipe.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int),
ctypes.c_void_p, ctypes.c_int]
_CreatePipe.restype = ctypes.c_int
_GetCurrentProcess = _kernel32.GetCurrentProcess
_GetCurrentProcess.argtypes = []
_GetCurrentProcess.restype = ctypes.c_int
GetVersion = _kernel32.GetVersion
GetVersion.argtypes = []
GetVersion.restype = ctypes.c_int
_DuplicateHandle = _kernel32.DuplicateHandle
_DuplicateHandle.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int,
ctypes.POINTER(ctypes.c_int),
ctypes.c_int, ctypes.c_int, ctypes.c_int]
_DuplicateHandle.restype = ctypes.c_int
_WaitForSingleObject = _kernel32.WaitForSingleObject
_WaitForSingleObject.argtypes = [ctypes.c_int, ctypes.c_uint]
_WaitForSingleObject.restype = ctypes.c_int
_GetExitCodeProcess = _kernel32.GetExitCodeProcess
_GetExitCodeProcess.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int)]
_GetExitCodeProcess.restype = ctypes.c_int
_TerminateProcess = _kernel32.TerminateProcess
_TerminateProcess.argtypes = [ctypes.c_int, ctypes.c_int]
_TerminateProcess.restype = ctypes.c_int
_GetStdHandle = _kernel32.GetStdHandle
_GetStdHandle.argtypes = [ctypes.c_int]
_GetStdHandle.restype = ctypes.c_int
class _STARTUPINFO(ctypes.Structure):
_fields_ = [('cb', ctypes.c_int),
('lpReserved', ctypes.c_void_p),
('lpDesktop', ctypes.c_char_p),
('lpTitle', ctypes.c_char_p),
('dwX', ctypes.c_int),
('dwY', ctypes.c_int),
('dwXSize', ctypes.c_int),
('dwYSize', ctypes.c_int),
('dwXCountChars', ctypes.c_int),
('dwYCountChars', ctypes.c_int),
("dwFillAttribute", ctypes.c_int),
("dwFlags", ctypes.c_int),
("wShowWindow", ctypes.c_short),
("cbReserved2", ctypes.c_short),
("lpReserved2", ctypes.c_void_p),
("hStdInput", ctypes.c_int),
("hStdOutput", ctypes.c_int),
("hStdError", ctypes.c_int)
]
class _PROCESS_INFORMATION(ctypes.Structure):
_fields_ = [("hProcess", ctypes.c_int),
("hThread", ctypes.c_int),
("dwProcessID", ctypes.c_int),
("dwThreadID", ctypes.c_int)]
_CreateProcess = _kernel32.CreateProcessA
_CreateProcess.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p, ctypes.c_void_p,
ctypes.c_int, ctypes.c_int, ctypes.c_char_p, ctypes.c_char_p,
ctypes.POINTER(_STARTUPINFO), ctypes.POINTER(_PROCESS_INFORMATION)]
_CreateProcess.restype = ctypes.c_int
del ctypes
# Now the _subprocess module implementation
from ctypes import c_int as _c_int, byref as _byref, WinError as _WinError
class _handle:
def __init__(self, handle):
self.handle = handle
def __int__(self):
return self.handle
def __del__(self):
if self.handle is not None:
_CloseHandle(self.handle)
def Detach(self):
handle, self.handle = self.handle, None
return handle
def Close(self):
if self.handle not in (-1, None):
_CloseHandle(self.handle)
self.handle = None
def CreatePipe(attributes, size):
read = _c_int()
write = _c_int()
res = _CreatePipe(_byref(read), _byref(write), None, size)
if not res:
raise _WinError()
return _handle(read.value), _handle(write.value)
def GetCurrentProcess():
return _handle(_GetCurrentProcess())
def DuplicateHandle(source_process, source, target_process, access, inherit, options=0):
target = _c_int()
res = _DuplicateHandle(int(source_process), int(source), int(target_process),
_byref(target),
access, inherit, options)
if not res:
raise _WinError()
return _handle(target.value)
def CreateProcess(name, command_line, process_attr, thread_attr,
inherit, flags, env, start_dir, startup_info):
si = _STARTUPINFO()
if startup_info is not None:
si.dwFlags = startup_info.dwFlags
si.wShowWindow = startup_info.wShowWindow
if startup_info.hStdInput:
si.hStdInput = int(startup_info.hStdInput)
if startup_info.hStdOutput:
si.hStdOutput = int(startup_info.hStdOutput)
if startup_info.hStdError:
si.hStdError = int(startup_info.hStdError)
pi = _PROCESS_INFORMATION()
if env is not None:
envbuf = ""
for k, v in env.iteritems():
envbuf += "%s=%s\0" % (k, v)
envbuf += '\0'
else:
envbuf = None
res = _CreateProcess(name, command_line, None, None, inherit, flags, envbuf,
start_dir, _byref(si), _byref(pi))
if not res:
raise _WinError()
return _handle(pi.hProcess), _handle(pi.hThread), pi.dwProcessID, pi.dwThreadID
def WaitForSingleObject(handle, milliseconds):
res = _WaitForSingleObject(int(handle), milliseconds)
if res < 0:
raise _WinError()
return res
def GetExitCodeProcess(handle):
code = _c_int()
res = _GetExitCodeProcess(int(handle), _byref(code))
if not res:
raise _WinError()
return code.value
def TerminateProcess(handle, exitcode):
res = _TerminateProcess(int(handle), exitcode)
if not res:
raise _WinError()
def GetStdHandle(stdhandle):
res = _GetStdHandle(stdhandle)
if not res:
return None
else:
return res
STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12
DUPLICATE_SAME_ACCESS = 2
STARTF_USESTDHANDLES = 0x100
STARTF_USESHOWWINDOW = 0x001
SW_HIDE = 0
INFINITE = 0xffffffff
WAIT_OBJECT_0 = 0
CREATE_NEW_CONSOLE = 0x010
CREATE_NEW_PROCESS_GROUP = 0x200
STILL_ACTIVE = 259
|