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 |