Package wafadmin :: Module pproc
[hide private]
[frames] | no frames]

Source Code for Module wafadmin.pproc

  1  # borrowed from python 2.5.2c1 
  2  # Copyright (c) 2003-2005 by Peter Astrand <astrand@lysator.liu.se> 
  3  # Licensed to PSF under a Contributor Agreement. 
  4   
  5  import sys 
  6  mswindows = (sys.platform == "win32") 
  7   
  8  import os 
  9  import types 
 10  import traceback 
 11  import gc 
 12   
13 -class CalledProcessError(Exception):
14 - def __init__(self, returncode, cmd):
15 self.returncode = returncode 16 self.cmd = cmd
17 - def __str__(self):
18 return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
19 20 if mswindows: 21 import threading 22 import msvcrt 23 if 0: 24 import pywintypes 25 from win32api import GetStdHandle, STD_INPUT_HANDLE, \ 26 STD_OUTPUT_HANDLE, STD_ERROR_HANDLE 27 from win32api import GetCurrentProcess, DuplicateHandle, \ 28 GetModuleFileName, GetVersion 29 from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE 30 from win32pipe import CreatePipe 31 from win32process import CreateProcess, STARTUPINFO, \ 32 GetExitCodeProcess, STARTF_USESTDHANDLES, \ 33 STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE 34 from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0 35 else: 36 from _subprocess import *
37 - class STARTUPINFO:
38 dwFlags = 0 39 hStdInput = None 40 hStdOutput = None 41 hStdError = None 42 wShowWindow = 0
43 - class pywintypes:
44 error = IOError
45 else: 46 import select 47 import errno 48 import fcntl 49 import pickle 50 51 __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"] 52 53 try: 54 MAXFD = os.sysconf("SC_OPEN_MAX") 55 except: 56 MAXFD = 256 57 58 try: 59 False 60 except NameError: 61 False = 0 62 True = 1 63 64 _active = [] 65
66 -def _cleanup():
67 for inst in _active[:]: 68 if inst.poll(_deadstate=sys.maxint) >= 0: 69 try: 70 _active.remove(inst) 71 except ValueError: 72 pass
73 74 PIPE = -1 75 STDOUT = -2 76 77
78 -def call(*popenargs, **kwargs):
79 return Popen(*popenargs, **kwargs).wait()
80
81 -def check_call(*popenargs, **kwargs):
82 retcode = call(*popenargs, **kwargs) 83 cmd = kwargs.get("args") 84 if cmd is None: 85 cmd = popenargs[0] 86 if retcode: 87 raise CalledProcessError(retcode, cmd) 88 return retcode
89 90
91 -def list2cmdline(seq):
92 result = [] 93 needquote = False 94 for arg in seq: 95 bs_buf = [] 96 97 if result: 98 result.append(' ') 99 100 needquote = (" " in arg) or ("\t" in arg) or arg == "" 101 if needquote: 102 result.append('"') 103 104 for c in arg: 105 if c == '\\': 106 bs_buf.append(c) 107 elif c == '"': 108 result.append('\\' * len(bs_buf)*2) 109 bs_buf = [] 110 result.append('\\"') 111 else: 112 if bs_buf: 113 result.extend(bs_buf) 114 bs_buf = [] 115 result.append(c) 116 117 if bs_buf: 118 result.extend(bs_buf) 119 120 if needquote: 121 result.extend(bs_buf) 122 result.append('"') 123 124 return ''.join(result)
125
126 -class Popen(object):
127 - def __init__(self, args, bufsize=0, executable=None, 128 stdin=None, stdout=None, stderr=None, 129 preexec_fn=None, close_fds=False, shell=False, 130 cwd=None, env=None, universal_newlines=False, 131 startupinfo=None, creationflags=0):
132 _cleanup() 133 134 self._child_created = False 135 if not isinstance(bufsize, (int, long)): 136 raise TypeError("bufsize must be an integer") 137 138 if mswindows: 139 if preexec_fn is not None: 140 raise ValueError("preexec_fn is not supported on Windows platforms") 141 if close_fds: 142 raise ValueError("close_fds is not supported on Windows platforms") 143 else: 144 if startupinfo is not None: 145 raise ValueError("startupinfo is only supported on Windows platforms") 146 if creationflags != 0: 147 raise ValueError("creationflags is only supported on Windows platforms") 148 149 self.stdin = None 150 self.stdout = None 151 self.stderr = None 152 self.pid = None 153 self.returncode = None 154 self.universal_newlines = universal_newlines 155 156 (p2cread, p2cwrite, 157 c2pread, c2pwrite, 158 errread, errwrite) = self._get_handles(stdin, stdout, stderr) 159 160 self._execute_child(args, executable, preexec_fn, close_fds, 161 cwd, env, universal_newlines, 162 startupinfo, creationflags, shell, 163 p2cread, p2cwrite, 164 c2pread, c2pwrite, 165 errread, errwrite) 166 167 if mswindows: 168 if stdin is None and p2cwrite is not None: 169 os.close(p2cwrite) 170 p2cwrite = None 171 if stdout is None and c2pread is not None: 172 os.close(c2pread) 173 c2pread = None 174 if stderr is None and errread is not None: 175 os.close(errread) 176 errread = None 177 178 if p2cwrite: 179 self.stdin = os.fdopen(p2cwrite, 'wb', bufsize) 180 if c2pread: 181 if universal_newlines: 182 self.stdout = os.fdopen(c2pread, 'rU', bufsize) 183 else: 184 self.stdout = os.fdopen(c2pread, 'rb', bufsize) 185 if errread: 186 if universal_newlines: 187 self.stderr = os.fdopen(errread, 'rU', bufsize) 188 else: 189 self.stderr = os.fdopen(errread, 'rb', bufsize)
190 191
192 - def _translate_newlines(self, data):
193 data = data.replace("\r\n", "\n") 194 data = data.replace("\r", "\n") 195 return data
196 197
198 - def __del__(self, sys=sys):
199 if not self._child_created: 200 return 201 self.poll(_deadstate=sys.maxint) 202 if self.returncode is None and _active is not None: 203 _active.append(self)
204 205
206 - def communicate(self, input=None):
207 if [self.stdin, self.stdout, self.stderr].count(None) >= 2: 208 stdout = None 209 stderr = None 210 if self.stdin: 211 if input: 212 self.stdin.write(input) 213 self.stdin.close() 214 elif self.stdout: 215 stdout = self.stdout.read() 216 elif self.stderr: 217 stderr = self.stderr.read() 218 self.wait() 219 return (stdout, stderr) 220 221 return self._communicate(input)
222 223 224 if mswindows:
225 - def _get_handles(self, stdin, stdout, stderr):
226 if stdin is None and stdout is None and stderr is None: 227 return (None, None, None, None, None, None) 228 229 p2cread, p2cwrite = None, None 230 c2pread, c2pwrite = None, None 231 errread, errwrite = None, None 232 233 if stdin is None: 234 p2cread = GetStdHandle(STD_INPUT_HANDLE) 235 if p2cread is not None: 236 pass 237 elif stdin is None or stdin == PIPE: 238 p2cread, p2cwrite = CreatePipe(None, 0) 239 p2cwrite = p2cwrite.Detach() 240 p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0) 241 elif isinstance(stdin, int): 242 p2cread = msvcrt.get_osfhandle(stdin) 243 else: 244 p2cread = msvcrt.get_osfhandle(stdin.fileno()) 245 p2cread = self._make_inheritable(p2cread) 246 247 if stdout is None: 248 c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE) 249 if c2pwrite is not None: 250 pass 251 elif stdout is None or stdout == PIPE: 252 c2pread, c2pwrite = CreatePipe(None, 0) 253 c2pread = c2pread.Detach() 254 c2pread = msvcrt.open_osfhandle(c2pread, 0) 255 elif isinstance(stdout, int): 256 c2pwrite = msvcrt.get_osfhandle(stdout) 257 else: 258 c2pwrite = msvcrt.get_osfhandle(stdout.fileno()) 259 c2pwrite = self._make_inheritable(c2pwrite) 260 261 if stderr is None: 262 errwrite = GetStdHandle(STD_ERROR_HANDLE) 263 if errwrite is not None: 264 pass 265 elif stderr is None or stderr == PIPE: 266 errread, errwrite = CreatePipe(None, 0) 267 errread = errread.Detach() 268 errread = msvcrt.open_osfhandle(errread, 0) 269 elif stderr == STDOUT: 270 errwrite = c2pwrite 271 elif isinstance(stderr, int): 272 errwrite = msvcrt.get_osfhandle(stderr) 273 else: 274 errwrite = msvcrt.get_osfhandle(stderr.fileno()) 275 errwrite = self._make_inheritable(errwrite) 276 277 return (p2cread, p2cwrite, 278 c2pread, c2pwrite, 279 errread, errwrite)
280 - def _make_inheritable(self, handle):
281 return DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), 0, 1, DUPLICATE_SAME_ACCESS)
282
283 - def _find_w9xpopen(self):
284 w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)), "w9xpopen.exe") 285 if not os.path.exists(w9xpopen): 286 w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix), "w9xpopen.exe") 287 if not os.path.exists(w9xpopen): 288 raise RuntimeError("Cannot locate w9xpopen.exe, which is needed for Popen to work with your shell or platform.") 289 return w9xpopen
290
291 - def _execute_child(self, args, executable, preexec_fn, close_fds, 292 cwd, env, universal_newlines, 293 startupinfo, creationflags, shell, 294 p2cread, p2cwrite, 295 c2pread, c2pwrite, 296 errread, errwrite):
297 298 if not isinstance(args, types.StringTypes): 299 args = list2cmdline(args) 300 301 if startupinfo is None: 302 startupinfo = STARTUPINFO() 303 if None not in (p2cread, c2pwrite, errwrite): 304 startupinfo.dwFlags |= STARTF_USESTDHANDLES 305 startupinfo.hStdInput = p2cread 306 startupinfo.hStdOutput = c2pwrite 307 startupinfo.hStdError = errwrite 308 309 if shell: 310 startupinfo.dwFlags |= STARTF_USESHOWWINDOW 311 startupinfo.wShowWindow = SW_HIDE 312 comspec = os.environ.get("COMSPEC", "cmd.exe") 313 args = comspec + " /c " + args 314 if (GetVersion() >= 0x80000000L or 315 os.path.basename(comspec).lower() == "command.com"): 316 w9xpopen = self._find_w9xpopen() 317 args = '"%s" %s' % (w9xpopen, args) 318 creationflags |= CREATE_NEW_CONSOLE 319 320 try: 321 hp, ht, pid, tid = CreateProcess(executable, args, None, None, 1, creationflags, env, cwd, startupinfo) 322 except pywintypes.error, e: 323 raise WindowsError(*e.args) 324 325 self._child_created = True 326 self._handle = hp 327 self.pid = pid 328 ht.Close() 329 330 if p2cread is not None: 331 p2cread.Close() 332 if c2pwrite is not None: 333 c2pwrite.Close() 334 if errwrite is not None: 335 errwrite.Close()
336 337
338 - def poll(self, _deadstate=None):
339 if self.returncode is None: 340 if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0: 341 self.returncode = GetExitCodeProcess(self._handle) 342 return self.returncode
343 344
345 - def wait(self):
346 if self.returncode is None: 347 obj = WaitForSingleObject(self._handle, INFINITE) 348 self.returncode = GetExitCodeProcess(self._handle) 349 return self.returncode
350
351 - def _readerthread(self, fh, buffer):
352 buffer.append(fh.read())
353
354 - def _communicate(self, input):
355 stdout = None 356 stderr = None 357 358 if self.stdout: 359 stdout = [] 360 stdout_thread = threading.Thread(target=self._readerthread, args=(self.stdout, stdout)) 361 stdout_thread.setDaemon(True) 362 stdout_thread.start() 363 if self.stderr: 364 stderr = [] 365 stderr_thread = threading.Thread(target=self._readerthread, args=(self.stderr, stderr)) 366 stderr_thread.setDaemon(True) 367 stderr_thread.start() 368 369 if self.stdin: 370 if input is not None: 371 self.stdin.write(input) 372 self.stdin.close() 373 374 if self.stdout: 375 stdout_thread.join() 376 if self.stderr: 377 stderr_thread.join() 378 379 if stdout is not None: 380 stdout = stdout[0] 381 if stderr is not None: 382 stderr = stderr[0] 383 384 if self.universal_newlines and hasattr(file, 'newlines'): 385 if stdout: 386 stdout = self._translate_newlines(stdout) 387 if stderr: 388 stderr = self._translate_newlines(stderr) 389 390 self.wait() 391 return (stdout, stderr)
392 393 else:
394 - def _get_handles(self, stdin, stdout, stderr):
395 p2cread, p2cwrite = None, None 396 c2pread, c2pwrite = None, None 397 errread, errwrite = None, None 398 399 if stdin is None: 400 pass 401 elif stdin == PIPE: 402 p2cread, p2cwrite = os.pipe() 403 elif isinstance(stdin, int): 404 p2cread = stdin 405 else: 406 p2cread = stdin.fileno() 407 408 if stdout is None: 409 pass 410 elif stdout == PIPE: 411 c2pread, c2pwrite = os.pipe() 412 elif isinstance(stdout, int): 413 c2pwrite = stdout 414 else: 415 c2pwrite = stdout.fileno() 416 417 if stderr is None: 418 pass 419 elif stderr == PIPE: 420 errread, errwrite = os.pipe() 421 elif stderr == STDOUT: 422 errwrite = c2pwrite 423 elif isinstance(stderr, int): 424 errwrite = stderr 425 else: 426 errwrite = stderr.fileno() 427 428 return (p2cread, p2cwrite, c2pread, c2pwrite, errread,