##// END OF EJS Templates
win32 iptest: Use subprocess.Popen() instead of os.system().
Bradley M. Froehle -
Show More
@@ -374,34 +374,16 b' class IPTester(object):'
374 # (on posix only, since win32 has no os.kill)
374 # (on posix only, since win32 has no os.kill)
375 self.pids = []
375 self.pids = []
376
376
377 if sys.platform == 'win32':
377 def _run_cmd(self):
378 def _run_cmd(self):
378 # print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg
379 # On Windows, use os.system instead of subprocess.call, because I
379 subp = subprocess.Popen(self.call_args)
380 # was having problems with subprocess and I just don't know enough
380 self.pids.append(subp.pid)
381 # about win32 to debug this reliably. Os.system may be the 'old
381 # If this fails, the pid will be left in self.pids and cleaned up
382 # fashioned' way to do it, but it works just fine. If someone
382 # later, but if the wait call succeeds, then we can clear the
383 # later can clean this up that's fine, as long as the tests run
383 # stored pid.
384 # reliably in win32.
384 retcode = subp.wait()
385 # What types of problems are you having. They may be related to
385 self.pids.pop()
386 # running Python in unboffered mode. BG.
386 return retcode
387 for ndx, arg in enumerate(self.call_args):
388 # Enclose in quotes if necessary and legal
389 if ' ' in arg and os.path.isfile(arg) and arg[0] != '"':
390 self.call_args[ndx] = '"%s"' % arg
391 call_args = [py3compat.cast_unicode(x) for x in self.call_args]
392 cmd = py3compat.unicode_to_str(u' '.join(call_args))
393 return os.system(cmd)
394 else:
395 def _run_cmd(self):
396 # print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg
397 subp = subprocess.Popen(self.call_args)
398 self.pids.append(subp.pid)
399 # If this fails, the pid will be left in self.pids and cleaned up
400 # later, but if the wait call succeeds, then we can clear the
401 # stored pid.
402 retcode = subp.wait()
403 self.pids.pop()
404 return retcode
405
387
406 def run(self):
388 def run(self):
407 """Run the stored commands"""
389 """Run the stored commands"""
@@ -416,17 +398,28 b' class IPTester(object):'
416 subprocess.call(["coverage", "xml", "-o", self.coverage_xml])
398 subprocess.call(["coverage", "xml", "-o", self.coverage_xml])
417 return retcode
399 return retcode
418
400
401 @staticmethod
402 def _kill(pid):
403 """Attempt to kill the process on a best effort basis."""
404 if hasattr(os, 'kill'):
405 os.kill(pid, signal.SIGKILL)
406 elif sys.platform == 'win32':
407 # Python 2.6 on Windows doesn't have os.kill.
408 from ctypes import windll
409 PROCESS_TERMINATE = 1
410 handle = windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, pid)
411 windll.kernel32.TerminateProcess(handle, -1)
412 windll.kernel32.CloseHandle(handle)
413 else:
414 raise NotImplementedError
415
419 def __del__(self):
416 def __del__(self):
420 """Cleanup on exit by killing any leftover processes."""
417 """Cleanup on exit by killing any leftover processes."""
421
422 if not hasattr(os, 'kill'):
423 return
424
425 for pid in self.pids:
418 for pid in self.pids:
426 try:
419 try:
427 print('Cleaning stale PID:', pid)
420 print('Cleaning stale PID:', pid)
428 os.kill(pid, signal.SIGKILL)
421 self._kill(pid)
429 except OSError:
422 except (OSError, NotImplementedError):
430 # This is just a best effort, if we fail or the process was
423 # This is just a best effort, if we fail or the process was
431 # really gone, ignore it.
424 # really gone, ignore it.
432 pass
425 pass
General Comments 0
You need to be logged in to leave comments. Login now