| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """A wrapper for subprocess to make calling shell commands easier.""" | 5 """A wrapper for subprocess to make calling shell commands easier.""" |
| 6 | 6 |
| 7 import os | 7 import os |
| 8 import logging | 8 import logging |
| 9 import signal |
| 9 import subprocess | 10 import subprocess |
| 11 import tempfile |
| 10 | 12 |
| 11 import constants | 13 import constants |
| 12 | 14 |
| 13 | 15 |
| 16 def _Call(args, stdout=None, stderr=None, shell=None, cwd=None): |
| 17 return subprocess.call( |
| 18 args=args, cwd=cwd, stdout=stdout, stderr=stderr, |
| 19 shell=shell, close_fds=True, |
| 20 preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL)) |
| 21 |
| 22 |
| 14 def RunCmd(args, cwd=None): | 23 def RunCmd(args, cwd=None): |
| 15 """Opens a subprocess to execute a program and returns its return value. | 24 """Opens a subprocess to execute a program and returns its return value. |
| 16 | 25 |
| 17 Args: | 26 Args: |
| 18 args: A string or a sequence of program arguments. The program to execute is | 27 args: A string or a sequence of program arguments. The program to execute is |
| 19 the string or the first item in the args sequence. | 28 the string or the first item in the args sequence. |
| 20 cwd: If not None, the subprocess's current directory will be changed to | 29 cwd: If not None, the subprocess's current directory will be changed to |
| 21 |cwd| before it's executed. | 30 |cwd| before it's executed. |
| 22 | 31 |
| 23 Returns: | 32 Returns: |
| 24 Return code from the command execution. | 33 Return code from the command execution. |
| 25 """ | 34 """ |
| 26 logging.info(str(args) + ' ' + (cwd or '')) | 35 logging.info(str(args) + ' ' + (cwd or '')) |
| 27 return subprocess.call(args, cwd=cwd) | 36 return _Call(args, cwd=cwd) |
| 28 | 37 |
| 29 | 38 |
| 30 def GetCmdOutput(args, cwd=None, shell=False): | 39 def GetCmdOutput(args, cwd=None, shell=False): |
| 31 """Open a subprocess to execute a program and returns its output. | 40 """Open a subprocess to execute a program and returns its output. |
| 32 | 41 |
| 33 Args: | 42 Args: |
| 34 args: A string or a sequence of program arguments. The program to execute is | 43 args: A string or a sequence of program arguments. The program to execute is |
| 35 the string or the first item in the args sequence. | 44 the string or the first item in the args sequence. |
| 36 cwd: If not None, the subprocess's current directory will be changed to | 45 cwd: If not None, the subprocess's current directory will be changed to |
| 37 |cwd| before it's executed. | 46 |cwd| before it's executed. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 52 args: A string or a sequence of program arguments. The program to execute is | 61 args: A string or a sequence of program arguments. The program to execute is |
| 53 the string or the first item in the args sequence. | 62 the string or the first item in the args sequence. |
| 54 cwd: If not None, the subprocess's current directory will be changed to | 63 cwd: If not None, the subprocess's current directory will be changed to |
| 55 |cwd| before it's executed. | 64 |cwd| before it's executed. |
| 56 shell: Whether to execute args as a shell command. | 65 shell: Whether to execute args as a shell command. |
| 57 | 66 |
| 58 Returns: | 67 Returns: |
| 59 The tuple (exit code, output). | 68 The tuple (exit code, output). |
| 60 """ | 69 """ |
| 61 logging.info(str(args) + ' ' + (cwd or '')) | 70 logging.info(str(args) + ' ' + (cwd or '')) |
| 62 p = subprocess.Popen(args=args, cwd=cwd, stdout=subprocess.PIPE, | 71 tmpout = tempfile.TemporaryFile(bufsize=0) |
| 63 stderr=subprocess.PIPE, shell=shell) | 72 tmperr = tempfile.TemporaryFile(bufsize=0) |
| 64 stdout, stderr = p.communicate() | 73 exit_code = _Call(args, cwd=cwd, stdout=tmpout, stderr=tmperr, shell=shell) |
| 65 exit_code = p.returncode | 74 tmperr.seek(0) |
| 75 stderr = tmperr.read() |
| 76 tmperr.close() |
| 66 if stderr: | 77 if stderr: |
| 67 logging.critical(stderr) | 78 logging.critical(stderr) |
| 79 tmpout.seek(0) |
| 80 stdout = tmpout.read() |
| 81 tmpout.close() |
| 68 logging.info(stdout[:4096]) # Truncate output longer than 4k. | 82 logging.info(stdout[:4096]) # Truncate output longer than 4k. |
| 69 return (exit_code, stdout) | 83 return (exit_code, stdout) |
| 70 | 84 |
| 71 | 85 |
| 72 class OutDirectory(object): | 86 class OutDirectory(object): |
| 73 _out_directory = os.path.join(constants.CHROME_DIR, 'out') | 87 _out_directory = os.path.join(constants.CHROME_DIR, 'out') |
| 74 @staticmethod | 88 @staticmethod |
| 75 def set(out_directory): | 89 def set(out_directory): |
| 76 OutDirectory._out_directory = out_directory | 90 OutDirectory._out_directory = out_directory |
| 77 @staticmethod | 91 @staticmethod |
| 78 def get(): | 92 def get(): |
| 79 return OutDirectory._out_directory | 93 return OutDirectory._out_directory |
| OLD | NEW |