| 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 import errno |
| 10 import logging | 11 import logging |
| 11 import os | 12 import os |
| 12 import subprocess | 13 import subprocess |
| 13 import sys | 14 import sys |
| 14 import tempfile | 15 import tempfile |
| 15 import time | 16 import time |
| 16 import threading | 17 import threading |
| 17 | 18 |
| 18 # Constants forwarded from subprocess. | 19 # Constants forwarded from subprocess. |
| 19 PIPE = subprocess.PIPE | 20 PIPE = subprocess.PIPE |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 env = env.copy() | 73 env = env.copy() |
| 73 def fix_lang(name): | 74 def fix_lang(name): |
| 74 if not is_english(name): | 75 if not is_english(name): |
| 75 env[name] = 'en_US.UTF-8' | 76 env[name] = 'en_US.UTF-8' |
| 76 fix_lang('LANG') | 77 fix_lang('LANG') |
| 77 fix_lang('LANGUAGE') | 78 fix_lang('LANGUAGE') |
| 78 return env | 79 return env |
| 79 | 80 |
| 80 | 81 |
| 81 def Popen(args, **kwargs): | 82 def Popen(args, **kwargs): |
| 82 """Wraps subprocess.Popen(). | 83 """Wraps subprocess.Popen() with various workarounds. |
| 83 | 84 |
| 84 Forces English output since it's easier to parse the stdout if it is always in | 85 Forces English output since it's easier to parse the stdout if it is always in |
| 85 English. | 86 English. |
| 86 | 87 |
| 87 Sets shell=True on windows by default. You can override this by forcing shell | 88 Sets shell=True on windows by default. You can override this by forcing shell |
| 88 parameter to a value. | 89 parameter to a value. |
| 89 | 90 |
| 90 Popen() can throw OSError when cwd or args[0] doesn't exist. | 91 Popen() can throw OSError when cwd or args[0] doesn't exist. Translate |
| 92 exceptions generated by cygwin when it fails trying to emulate fork(). |
| 91 """ | 93 """ |
| 92 # Make sure we hack subprocess if necessary. | 94 # Make sure we hack subprocess if necessary. |
| 93 hack_subprocess() | 95 hack_subprocess() |
| 94 | 96 |
| 95 env = get_english_env(kwargs.get('env')) | 97 env = get_english_env(kwargs.get('env')) |
| 96 if env: | 98 if env: |
| 97 kwargs['env'] = env | 99 kwargs['env'] = env |
| 98 | 100 |
| 99 if not kwargs.get('shell') is None: | 101 if not kwargs.get('shell') is None: |
| 100 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the | 102 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the |
| 101 # executable, but shell=True makes subprocess on Linux fail when it's called | 103 # executable, but shell=True makes subprocess on Linux fail when it's called |
| 102 # with a list because it only tries to execute the first item in the list. | 104 # with a list because it only tries to execute the first item in the list. |
| 103 kwargs['shell'] = (sys.platform=='win32') | 105 kwargs['shell'] = (sys.platform=='win32') |
| 104 | 106 |
| 105 tmp_str = ' '.join(args) | 107 tmp_str = ' '.join(args) |
| 106 if kwargs.get('cwd', None): | 108 if kwargs.get('cwd', None): |
| 107 tmp_str += '; cwd=%s' % kwargs['cwd'] | 109 tmp_str += '; cwd=%s' % kwargs['cwd'] |
| 108 logging.debug(tmp_str) | 110 logging.debug(tmp_str) |
| 109 return subprocess.Popen(args, **kwargs) | 111 try: |
| 112 return subprocess.Popen(args, **kwargs) |
| 113 except OSError, e: |
| 114 if e.errno == errno.EAGAIN and sys.platform == 'cygwin': |
| 115 # Convert fork() emulation failure into a CalledProcessError(). |
| 116 raise CalledProcessError( |
| 117 e.errno, |
| 118 args, |
| 119 kwargs.get('cwd'), |
| 120 'Visit ' |
| 121 'http://code.google.com/p/chromium/wiki/CygwinDllRemappingFailure to ' |
| 122 'learn how to fix this error; you need to rebase your cygwin dlls', |
| 123 None) |
| 124 raise |
| 110 | 125 |
| 111 | 126 |
| 112 def call(args, timeout=None, **kwargs): | 127 def call(args, timeout=None, **kwargs): |
| 113 """Wraps subprocess.Popen().communicate(). | 128 """Wraps subprocess.Popen().communicate(). |
| 114 | 129 |
| 115 The process will be kill with error code -9 after |timeout| seconds if set. | 130 The process will be kill with error code -9 after |timeout| seconds if set. |
| 116 | 131 |
| 117 Automatically passes stdin content as input so do not specify stdin=PIPE. | 132 Automatically passes stdin content as input so do not specify stdin=PIPE. |
| 118 | 133 |
| 119 Returns both communicate() tuple and return code wrapped in a tuple. | 134 Returns both communicate() tuple and return code wrapped in a tuple. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 208 |
| 194 Discards communicate()[1]. By default sets stderr=STDOUT. | 209 Discards communicate()[1]. By default sets stderr=STDOUT. |
| 195 | 210 |
| 196 Throws if return code is not 0. | 211 Throws if return code is not 0. |
| 197 | 212 |
| 198 Works even prior to python 2.7. | 213 Works even prior to python 2.7. |
| 199 """ | 214 """ |
| 200 if kwargs.get('stderr') is None: | 215 if kwargs.get('stderr') is None: |
| 201 kwargs['stderr'] = STDOUT | 216 kwargs['stderr'] = STDOUT |
| 202 return check_call(args, stdout=PIPE, **kwargs)[0] | 217 return check_call(args, stdout=PIPE, **kwargs)[0] |
| OLD | NEW |