| 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 |
| 20 # Constants forwarded from subprocess. | 21 # Constants forwarded from subprocess. |
| 21 PIPE = subprocess.PIPE | 22 PIPE = subprocess.PIPE |
| 22 STDOUT = subprocess.STDOUT | 23 STDOUT = subprocess.STDOUT |
| 23 # Sends stdout or stderr to os.devnull. | 24 # Sends stdout or stderr to os.devnull. |
| 24 VOID = object() | 25 VOID = object() |
| 25 # Error code when a process was killed because it timed out. | 26 # Error code when a process was killed because it timed out. |
| 26 TIMED_OUT = -2001 | 27 TIMED_OUT = -2001 |
| 27 | 28 |
| 28 # Globals. | 29 # Globals. |
| 29 # Set to True if you somehow need to disable this hack. | 30 # Set to True if you somehow need to disable this hack. |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 # Create a temporary file to workaround python's deadlock. | 176 # Create a temporary file to workaround python's deadlock. |
| 176 # http://docs.python.org/library/subprocess.html#subprocess.Popen.wait | 177 # http://docs.python.org/library/subprocess.html#subprocess.Popen.wait |
| 177 # When the pipe fills up, it will deadlock this process. Using a real | 178 # When the pipe fills up, it will deadlock this process. Using a real |
| 178 # file works around that issue. | 179 # file works around that issue. |
| 179 kwargs[stream] = open(os.devnull, 'w') | 180 kwargs[stream] = open(os.devnull, 'w') |
| 180 | 181 |
| 181 fix('stdout') | 182 fix('stdout') |
| 182 fix('stderr') | 183 fix('stderr') |
| 183 | 184 |
| 184 self.start = time.time() | 185 self.start = time.time() |
| 186 self.shell = kwargs.get('shell', None) |
| 185 # Silence pylint on MacOSX | 187 # Silence pylint on MacOSX |
| 186 self.returncode = None | 188 self.returncode = None |
| 189 |
| 187 try: | 190 try: |
| 188 super(Popen, self).__init__(args, **kwargs) | 191 super(Popen, self).__init__(args, **kwargs) |
| 189 except OSError, e: | 192 except OSError, e: |
| 190 if e.errno == errno.EAGAIN and sys.platform == 'cygwin': | 193 if e.errno == errno.EAGAIN and sys.platform == 'cygwin': |
| 191 # Convert fork() emulation failure into a CygwinRebaseError(). | 194 # Convert fork() emulation failure into a CygwinRebaseError(). |
| 192 raise CygwinRebaseError( | 195 raise CygwinRebaseError( |
| 193 e.errno, | 196 e.errno, |
| 194 args, | 197 args, |
| 195 kwargs.get('cwd'), | 198 kwargs.get('cwd'), |
| 196 None, | 199 None, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 else: | 234 else: |
| 232 return proc.communicate(), proc.returncode | 235 return proc.communicate(), proc.returncode |
| 233 | 236 |
| 234 # Create a temporary file to workaround python's deadlock. | 237 # Create a temporary file to workaround python's deadlock. |
| 235 # http://docs.python.org/library/subprocess.html#subprocess.Popen.wait | 238 # http://docs.python.org/library/subprocess.html#subprocess.Popen.wait |
| 236 # When the pipe fills up, it will deadlock this process. Using a real file | 239 # When the pipe fills up, it will deadlock this process. Using a real file |
| 237 # works around that issue. | 240 # works around that issue. |
| 238 with tempfile.TemporaryFile() as buff: | 241 with tempfile.TemporaryFile() as buff: |
| 239 kwargs['stdout'] = buff | 242 kwargs['stdout'] = buff |
| 240 proc = Popen(args, **kwargs) | 243 proc = Popen(args, **kwargs) |
| 244 if proc.shell: |
| 245 raise TypeError( |
| 246 'Using timeout and shell simultaneously will cause a process leak ' |
| 247 'since the shell will be killed instead of the child process.') |
| 241 if stdin is not None: | 248 if stdin is not None: |
| 242 proc.stdin.write(stdin) | 249 proc.stdin.write(stdin) |
| 243 while proc.returncode is None: | 250 while proc.returncode is None: |
| 244 proc.poll() | 251 proc.poll() |
| 245 if timeout and (time.time() - proc.start) > timeout: | 252 if timeout and (time.time() - proc.start) > timeout: |
| 246 proc.kill() | 253 proc.kill() |
| 247 proc.wait() | 254 proc.wait() |
| 248 # It's -9 on linux and 1 on Windows. Standardize to TIMED_OUT. | 255 # It's -9 on linux and 1 on Windows. Standardize to TIMED_OUT. |
| 249 proc.returncode = TIMED_OUT | 256 proc.returncode = TIMED_OUT |
| 250 time.sleep(0.001) | 257 time.sleep(0.001) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 | 314 |
| 308 - Throws if return code is not 0. | 315 - Throws if return code is not 0. |
| 309 - Works even prior to python 2.7. | 316 - Works even prior to python 2.7. |
| 310 - Blocks stdin by default if not specified since no output will be visible. | 317 - Blocks stdin by default if not specified since no output will be visible. |
| 311 - As per doc, "The stdout argument is not allowed as it is used internally." | 318 - As per doc, "The stdout argument is not allowed as it is used internally." |
| 312 """ | 319 """ |
| 313 kwargs.setdefault('stdin', VOID) | 320 kwargs.setdefault('stdin', VOID) |
| 314 if 'stdout' in kwargs: | 321 if 'stdout' in kwargs: |
| 315 raise ValueError('stdout argument not allowed, it will be overridden.') | 322 raise ValueError('stdout argument not allowed, it will be overridden.') |
| 316 return check_call_out(args, stdout=PIPE, **kwargs)[0] | 323 return check_call_out(args, stdout=PIPE, **kwargs)[0] |
| OLD | NEW |