Home | History | Annotate | Download | only in android_testrunner
      1 diff --git a/third_party/android_testrunner/run_command.py b/third_party/android_testrunner/run_command.py
      2 index 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