| 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 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 self.cwd = cwd | 34 self.cwd = cwd |
| 35 | 35 |
| 36 def __str__(self): | 36 def __str__(self): |
| 37 out = 'Command %s returned non-zero exit status %s' % ( | 37 out = 'Command %s returned non-zero exit status %s' % ( |
| 38 ' '.join(self.cmd), self.returncode) | 38 ' '.join(self.cmd), self.returncode) |
| 39 if self.cwd: | 39 if self.cwd: |
| 40 out += ' in ' + self.cwd | 40 out += ' in ' + self.cwd |
| 41 return '\n'.join(filter(None, (out, self.stdout, self.stderr))) | 41 return '\n'.join(filter(None, (out, self.stdout, self.stderr))) |
| 42 | 42 |
| 43 | 43 |
| 44 ## Utility functions |
| 45 |
| 46 |
| 47 def kill_pid(pid): |
| 48 """Kills a process by its process id.""" |
| 49 try: |
| 50 # Unable to import 'module' |
| 51 # pylint: disable=F0401 |
| 52 import signal |
| 53 return os.kill(pid, signal.SIGKILL) |
| 54 except ImportError: |
| 55 pass |
| 56 |
| 57 |
| 58 def kill_win(process): |
| 59 """Kills a process with its windows handle. |
| 60 |
| 61 Has no effect on other platforms. |
| 62 """ |
| 63 try: |
| 64 # Unable to import 'module' |
| 65 # pylint: disable=F0401 |
| 66 import win32process |
| 67 # Access to a protected member _handle of a client class |
| 68 # pylint: disable=W0212 |
| 69 return win32process.TerminateProcess(process._handle, -1) |
| 70 except ImportError: |
| 71 pass |
| 72 |
| 73 |
| 74 def add_kill(): |
| 75 """Adds kill() method to subprocess.Popen for python <2.6""" |
| 76 if hasattr(subprocess.Popen, 'kill'): |
| 77 return |
| 78 |
| 79 if sys.platform == 'win32': |
| 80 subprocess.Popen.kill = kill_win |
| 81 else: |
| 82 subprocess.Popen.kill = lambda process: kill_pid(process.pid) |
| 83 |
| 84 |
| 44 def hack_subprocess(): | 85 def hack_subprocess(): |
| 45 """subprocess functions may throw exceptions when used in multiple threads. | 86 """subprocess functions may throw exceptions when used in multiple threads. |
| 46 | 87 |
| 47 See http://bugs.python.org/issue1731717 for more information. | 88 See http://bugs.python.org/issue1731717 for more information. |
| 48 """ | 89 """ |
| 49 global SUBPROCESS_CLEANUP_HACKED | 90 global SUBPROCESS_CLEANUP_HACKED |
| 50 if not SUBPROCESS_CLEANUP_HACKED and threading.activeCount() != 1: | 91 if not SUBPROCESS_CLEANUP_HACKED and threading.activeCount() != 1: |
| 51 # Only hack if there is ever multiple threads. | 92 # Only hack if there is ever multiple threads. |
| 52 # There is no point to leak with only one thread. | 93 # There is no point to leak with only one thread. |
| 53 subprocess._cleanup = lambda: None | 94 subprocess._cleanup = lambda: None |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 Forces English output since it's easier to parse the stdout if it is always in | 126 Forces English output since it's easier to parse the stdout if it is always in |
| 86 English. | 127 English. |
| 87 | 128 |
| 88 Sets shell=True on windows by default. You can override this by forcing shell | 129 Sets shell=True on windows by default. You can override this by forcing shell |
| 89 parameter to a value. | 130 parameter to a value. |
| 90 | 131 |
| 91 Popen() can throw OSError when cwd or args[0] doesn't exist. | 132 Popen() can throw OSError when cwd or args[0] doesn't exist. |
| 92 """ | 133 """ |
| 93 # Make sure we hack subprocess if necessary. | 134 # Make sure we hack subprocess if necessary. |
| 94 hack_subprocess() | 135 hack_subprocess() |
| 136 add_kill() |
| 95 | 137 |
| 96 env = get_english_env(kwargs.get('env')) | 138 env = get_english_env(kwargs.get('env')) |
| 97 if env: | 139 if env: |
| 98 kwargs['env'] = env | 140 kwargs['env'] = env |
| 99 | 141 |
| 100 if not kwargs.get('shell') is None: | 142 if not kwargs.get('shell') is None: |
| 101 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the | 143 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the |
| 102 # executable, but shell=True makes subprocess on Linux fail when it's called | 144 # executable, but shell=True makes subprocess on Linux fail when it's called |
| 103 # with a list because it only tries to execute the first item in the list. | 145 # with a list because it only tries to execute the first item in the list. |
| 104 kwargs['shell'] = (sys.platform=='win32') | 146 kwargs['shell'] = (sys.platform=='win32') |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 236 |
| 195 Discards communicate()[1]. By default sets stderr=STDOUT. | 237 Discards communicate()[1]. By default sets stderr=STDOUT. |
| 196 | 238 |
| 197 Throws if return code is not 0. | 239 Throws if return code is not 0. |
| 198 | 240 |
| 199 Works even prior to python 2.7. | 241 Works even prior to python 2.7. |
| 200 """ | 242 """ |
| 201 if kwargs.get('stderr') is None: | 243 if kwargs.get('stderr') is None: |
| 202 kwargs['stderr'] = STDOUT | 244 kwargs['stderr'] = STDOUT |
| 203 return check_call(args, stdout=PIPE, **kwargs)[0] | 245 return check_call(args, stdout=PIPE, **kwargs)[0] |
| OLD | NEW |