#!/usr/bin/python # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os import signal import subprocess import time class BrowserProcessBase(object): def __init__(self, handle): self.handle = handle print 'PID', self.handle.pid def GetReturnCode(self): return self.handle.returncode def IsRunning(self): return self.handle.poll() is None def Wait(self, wait_steps, sleep_time): try: self.term() except Exception: # Terminating the handle can raise an exception. There is likely no point # in waiting if the termination didn't succeed. return i = 0 # subprocess.wait() doesn't have a timeout, unfortunately. while self.IsRunning() and i < wait_steps: time.sleep(sleep_time) i += 1 def Kill(self): if self.IsRunning(): print 'KILLING the browser' try: self.kill() # If it doesn't die, we hang. Oh well. self.handle.wait() except Exception: # If it is already dead, then it's ok. # This may happen if the browser dies after the first poll, but # before the kill. if self.IsRunning(): raise class BrowserProcess(BrowserProcessBase): def term(self): self.handle.terminate() def kill(self): self.handle.kill() class BrowserProcessPosix(BrowserProcessBase): """ This variant of BrowserProcess uses process groups to manage browser life time. """ def term(self): os.killpg(self.handle.pid, signal.SIGTERM) def kill(self): os.killpg(self.handle.pid, signal.SIGKILL) def RunCommandWithSubprocess(cmd, env=None): handle = subprocess.Popen(cmd, env=env) return BrowserProcess(handle) def RunCommandInProcessGroup(cmd, env=None): def SetPGrp(): os.setpgrp() print 'I\'M THE SESSION LEADER!' handle = subprocess.Popen(cmd, env=env, preexec_fn=SetPGrp) return BrowserProcessPosix(handle)