1diff --git a/third_party/android_testrunner/run_command.py b/third_party/android_testrunner/run_command.py 2index d398daa..6b84156 100644 3--- a/third_party/android_testrunner/run_command.py 4+++ b/third_party/android_testrunner/run_command.py 5@@ -19,6 +19,7 @@ 6 import os 7 import signal 8 import subprocess 9+import tempfile 10 import threading 11 import time 12 13@@ -80,31 +81,36 @@ def RunOnce(cmd, timeout_time=None, return_output=True, stdin_input=None): 14 """ 15 start_time = time.time() 16 so = [] 17- pid = [] 18 global _abort_on_error, error_occurred 19 error_occurred = False 20 21+ if return_output: 22+ output_dest = tempfile.TemporaryFile(bufsize=0) 23+ else: 24+ # None means direct to stdout 25+ output_dest = None 26+ if stdin_input: 27+ stdin_dest = subprocess.PIPE 28+ else: 29+ stdin_dest = None 30+ pipe = subprocess.Popen( 31+ cmd, 32+ executable='/bin/bash', 33+ stdin=stdin_dest, 34+ stdout=output_dest, 35+ stderr=subprocess.STDOUT, 36+ shell=True, close_fds=True, 37+ preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL)) 38+ 39 def Run(): 40 global error_occurred 41- if return_output: 42- output_dest = subprocess.PIPE 43- else: 44- # None means direct to stdout 45- output_dest = None 46- if stdin_input: 47- stdin_dest = subprocess.PIPE 48- else: 49- stdin_dest = None 50- pipe = subprocess.Popen( 51- cmd, 52- executable='/bin/bash', 53- stdin=stdin_dest, 54- stdout=output_dest, 55- stderr=subprocess.STDOUT, 56- shell=True) 57- pid.append(pipe.pid) 58 try: 59- output = pipe.communicate(input=stdin_input)[0] 60+ pipe.communicate(input=stdin_input) 61+ output = None 62+ if return_output: 63+ output_dest.seek(0) 64+ output = output_dest.read() 65+ output_dest.close() 66 if output is not None and len(output) > 0: 67 so.append(output) 68 except OSError, e: 69@@ -119,27 +125,17 @@ def RunOnce(cmd, timeout_time=None, return_output=True, stdin_input=None): 70 71 t = threading.Thread(target=Run) 72 t.start() 73- 74- break_loop = False 75- while not break_loop: 76- if not t.isAlive(): 77- break_loop = True 78- 79- # Check the timeout 80- if (not break_loop and timeout_time is not None 81- and time.time() > start_time + timeout_time): 82- try: 83- os.kill(pid[0], signal.SIGKILL) 84- except OSError: 85- # process already dead. No action required. 86- pass 87- 88+ t.join(timeout_time) 89+ if t.isAlive(): 90+ try: 91+ pipe.kill() 92+ except OSError: 93+ # Can't kill a dead process. 94+ pass 95+ finally: 96 logger.SilentLog("about to raise a timeout for: %s" % cmd) 97 raise errors.WaitForResponseTimedOutError 98- if not break_loop: 99- time.sleep(0.1) 100 101- t.join() 102 output = "".join(so) 103 if _abort_on_error and error_occurred: 104 raise errors.AbortError(msg=output) 105