Chromium Code Reviews| Index: runtime/tools/utils.py |
| diff --git a/runtime/tools/utils.py b/runtime/tools/utils.py |
| index 7cf34bee553af2f9b10a63867971a8b966873b72..78b4993eb93bdfb0cbea06f0dd38f73a5707a231 100644 |
| --- a/runtime/tools/utils.py |
| +++ b/runtime/tools/utils.py |
| @@ -5,10 +5,16 @@ |
| # This file contains a set of utilities functions used by other Python-based |
| # scripts. |
| +import commands |
| +import os |
| import platform |
| +import Queue |
| import re |
| -import os |
| -import commands |
| +import StringIO |
| +import subprocess |
| +import sys |
| +import threading |
| +import time |
| # Try to guess the host operating system. |
| @@ -128,12 +134,113 @@ def GetBuildConf(mode, arch): |
| return GetBuildMode(mode) + arch.upper() |
| -def GetBuildRoot(target_os, mode=None, arch=None): |
| +def GetBuildRoot(host_os, mode=None, arch=None): |
| global BUILD_ROOT |
| if mode: |
| - return os.path.join(BUILD_ROOT[target_os], GetBuildConf(mode, arch)) |
| + return os.path.join(BUILD_ROOT[host_os], GetBuildConf(mode, arch)) |
| else: |
| - return BUILD_ROOT[target_os] |
| + return BUILD_ROOT[host_os] |
| + |
| + |
| +def RunCommand(command, input=None, pollFn=None, outStream=None, errStream=None, |
| + killOnEarlyReturn=True, verbose=False, debug=False, |
| + printErrorInfo=False): |
| + """ |
| + Run a command, with optional input and polling function. |
| + command is a list of the command and its arguments. |
| + Input is an optional string of input to feed to the command, it should be |
| + short enough to fit in an i/o pipe buffer. |
| + The pollFn is called occasionally to check if the command should be finished |
|
Emily Fortuna
2012/08/28 16:49:14
Comment formatting:
"""
Function Description.
Ar
jackpal
2012/08/28 20:15:20
Done.
|
| + early. |
| + If pollFn returns True then the command will finish early. |
| + If outStream is not None, the stdout output of the command will be written to |
| + outStream. |
| + If errStream is not None, the stderr output of the command will be written to |
| + errStream. |
| + If pollFn returns True and killOnEarlyReturn is True, then the subprocess |
| + will be killed, otherwise the subprocess will be detached. |
| + If verbose is True, echos command arguments. |
| + If debug is True, prints debugging information. |
| + If printErrorInfo is True, prints error information when the command returns a |
| + non-zero exit code. |
| + Returns the output of the command. |
| + Raises an exception if the command returns an error code. |
| + """ |
| + if verbose: |
| + sys.stderr.write("command %s\n" % command) |
| + stdin = None |
| + if input is not None: |
| + stdin = subprocess.PIPE |
| + try: |
| + process = subprocess.Popen(args=command, |
| + stdin=stdin, |
| + bufsize=1, |
| + stdout=subprocess.PIPE, |
| + stderr=subprocess.PIPE) |
| + except Exception as e: |
| + if not isinstance(command, basestring): |
| + command = ' '.join(command) |
| + if printErrorInfo: |
| + sys.stderr.write("Command failed: '%s'\n" % command) |
| + raise e |
| + |
| + def StartThread(out): |
| + queue = Queue.Queue() |
| + def EnqueueOutput(out, queue): |
| + for line in iter(out.readline, b''): |
| + queue.put(line) |
| + out.close() |
| + thread = threading.Thread(target=EnqueueOutput, args=(out, queue)) |
| + thread.daemon = True |
| + thread.start() |
| + return queue |
| + outQueue = StartThread(process.stdout) |
| + errQueue = StartThread(process.stderr) |
| + |
| + def ReadQueue(queue, out, out2): |
| + try: |
| + while True: |
| + line = queue.get(False) |
| + out.write(line) |
| + if out2 != None: |
| + out2.write(line) |
| + except Queue.Empty: |
| + pass |
| + |
| + outBuf = StringIO.StringIO() |
| + errorBuf = StringIO.StringIO() |
| + if input != None: |
| + process.stdin.write(input) |
| + while True: |
| + returncode = process.poll() |
| + if returncode != None: |
| + break |
| + ReadQueue(errQueue, errorBuf, errStream) |
| + ReadQueue(outQueue, outBuf, outStream) |
| + if pollFn != None and pollFn(): |
| + returncode = 0 |
| + if killOnEarlyReturn: |
| + process.kill() |
| + break |
| + time.sleep(0.1) |
| + # Drain queue |
| + ReadQueue(errQueue, errorBuf, errStream) |
| + ReadQueue(outQueue, outBuf, outStream) |
| + |
| + out = outBuf.getvalue(); |
| + error = errorBuf.getvalue(); |
| + if returncode != 0: |
| + if not isinstance(command, basestring): |
| + command = ' '.join(command) |
| + if printErrorInfo: |
| + sys.stderr.write("Command failed: '%s'\n" % command) |
| + sys.stderr.write(" stdout: '%s'\n" % out) |
| + sys.stderr.write(" stderr: '%s'\n" % error) |
| + sys.stderr.write(" returncode: %d\n" % returncode) |
| + raise Exception("Command failed: %s" % command) |
| + if debug: |
| + sys.stderr.write("output: %s\n" % out) |
| + return out |
| def Main(argv): |