• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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