| OLD | NEW |
| 1 # coding=utf8 | 1 # coding=utf8 |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 """Collection of subprocess wrapper functions. | 5 """Collection of subprocess wrapper functions. |
| 6 | 6 |
| 7 In theory you shouldn't need anything else in subprocess, or this module failed. | 7 In theory you shouldn't need anything else in subprocess, or this module failed. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 from __future__ import with_statement | 10 from __future__ import with_statement |
| 11 import errno | 11 import errno |
| 12 import logging | 12 import logging |
| 13 import os | 13 import os |
| 14 import subprocess | 14 import subprocess |
| 15 import sys | 15 import sys |
| 16 import tempfile | 16 import tempfile |
| 17 import time | 17 import time |
| 18 import threading | 18 import threading |
| 19 | 19 |
| 20 # Constants forwarded from subprocess. | 20 # Constants forwarded from subprocess. |
| 21 PIPE = subprocess.PIPE | 21 PIPE = subprocess.PIPE |
| 22 STDOUT = subprocess.STDOUT | 22 STDOUT = subprocess.STDOUT |
| 23 # Sends stdout or stderr to os.devnull. | 23 # Sends stdout or stderr to os.devnull. |
| 24 VOID = '/dev/null' | 24 VOID = object() |
| 25 # Error code when a process was killed because it timed out. | 25 # Error code when a process was killed because it timed out. |
| 26 TIMED_OUT = -2001 | 26 TIMED_OUT = -2001 |
| 27 | 27 |
| 28 # Globals. | 28 # Globals. |
| 29 # Set to True if you somehow need to disable this hack. | 29 # Set to True if you somehow need to disable this hack. |
| 30 SUBPROCESS_CLEANUP_HACKED = False | 30 SUBPROCESS_CLEANUP_HACKED = False |
| 31 | 31 |
| 32 | 32 |
| 33 class CalledProcessError(subprocess.CalledProcessError): | 33 class CalledProcessError(subprocess.CalledProcessError): |
| 34 """Augment the standard exception with more data.""" | 34 """Augment the standard exception with more data.""" |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 """Wraps subprocess.Popen().communicate(). | 196 """Wraps subprocess.Popen().communicate(). |
| 197 | 197 |
| 198 Returns ((stdout, stderr), returncode). | 198 Returns ((stdout, stderr), returncode). |
| 199 | 199 |
| 200 - The process will be killed after |timeout| seconds and returncode set to | 200 - The process will be killed after |timeout| seconds and returncode set to |
| 201 TIMED_OUT. | 201 TIMED_OUT. |
| 202 - Automatically passes stdin content as input so do not specify stdin=PIPE. | 202 - Automatically passes stdin content as input so do not specify stdin=PIPE. |
| 203 """ | 203 """ |
| 204 stdin = kwargs.pop('stdin', None) | 204 stdin = kwargs.pop('stdin', None) |
| 205 if stdin is not None: | 205 if stdin is not None: |
| 206 assert stdin != PIPE | 206 if stdin is VOID: |
| 207 # When stdin is passed as an argument, use it as the actual input data and | 207 kwargs['stdin'] = open(os.devnull, 'r') |
| 208 # set the Popen() parameter accordingly. | 208 stdin = None |
| 209 kwargs['stdin'] = PIPE | 209 else: |
| 210 assert isinstance(stdin, str) |
| 211 # When stdin is passed as an argument, use it as the actual input data and |
| 212 # set the Popen() parameter accordingly. |
| 213 kwargs['stdin'] = PIPE |
| 210 | 214 |
| 211 if not timeout: | 215 if not timeout: |
| 212 # Normal workflow. | 216 # Normal workflow. |
| 213 proc = Popen(args, **kwargs) | 217 proc = Popen(args, **kwargs) |
| 214 if stdin is not None: | 218 if stdin is not None: |
| 215 return proc.communicate(stdin), proc.returncode | 219 return proc.communicate(stdin), proc.returncode |
| 216 else: | 220 else: |
| 217 return proc.communicate(), proc.returncode | 221 return proc.communicate(), proc.returncode |
| 218 | 222 |
| 219 # Create a temporary file to workaround python's deadlock. | 223 # Create a temporary file to workaround python's deadlock. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 - Works even prior to python 2.7. | 284 - Works even prior to python 2.7. |
| 281 - Blocks stdin by default since no output will be visible. | 285 - Blocks stdin by default since no output will be visible. |
| 282 """ | 286 """ |
| 283 if kwargs.get('stdin') is None: | 287 if kwargs.get('stdin') is None: |
| 284 kwargs['stdin'] = VOID | 288 kwargs['stdin'] = VOID |
| 285 if kwargs.get('stdout') is None: | 289 if kwargs.get('stdout') is None: |
| 286 kwargs['stdout'] = PIPE | 290 kwargs['stdout'] = PIPE |
| 287 if kwargs.get('stderr') is None: | 291 if kwargs.get('stderr') is None: |
| 288 kwargs['stderr'] = STDOUT | 292 kwargs['stderr'] = STDOUT |
| 289 return check_call(args, **kwargs)[0] | 293 return check_call(args, **kwargs)[0] |
| OLD | NEW |