| 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 logging | 12 import logging |
| 12 import os | 13 import os |
| 13 import subprocess | 14 import subprocess |
| 14 import sys | 15 import sys |
| 15 import tempfile | 16 import tempfile |
| 16 import time | 17 import time |
| 17 import threading | 18 import threading |
| 18 | 19 |
| 19 # Constants forwarded from subprocess. | 20 # Constants forwarded from subprocess. |
| 20 PIPE = subprocess.PIPE | 21 PIPE = subprocess.PIPE |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 env = env.copy() | 118 env = env.copy() |
| 118 def fix_lang(name): | 119 def fix_lang(name): |
| 119 if not is_english(name): | 120 if not is_english(name): |
| 120 env[name] = 'en_US.UTF-8' | 121 env[name] = 'en_US.UTF-8' |
| 121 fix_lang('LANG') | 122 fix_lang('LANG') |
| 122 fix_lang('LANGUAGE') | 123 fix_lang('LANGUAGE') |
| 123 return env | 124 return env |
| 124 | 125 |
| 125 | 126 |
| 126 def Popen(args, **kwargs): | 127 def Popen(args, **kwargs): |
| 127 """Wraps subprocess.Popen(). | 128 """Wraps subprocess.Popen() with various workarounds. |
| 128 | 129 |
| 129 Returns a subprocess.Popen object. | 130 Returns a subprocess.Popen object. |
| 130 | 131 |
| 131 - Forces English output since it's easier to parse the stdout if it is always | 132 - Forces English output since it's easier to parse the stdout if it is always |
| 132 in English. | 133 in English. |
| 133 - Sets shell=True on windows by default. You can override this by forcing | 134 - Sets shell=True on windows by default. You can override this by forcing |
| 134 shell parameter to a value. | 135 shell parameter to a value. |
| 135 - Adds support for VOID to not buffer when not needed. | 136 - Adds support for VOID to not buffer when not needed. |
| 136 | 137 |
| 137 Note: Popen() can throw OSError when cwd or args[0] doesn't exist. | 138 Note: Popen() can throw OSError when cwd or args[0] doesn't exist. Translate |
| 139 exceptions generated by cygwin when it fails trying to emulate fork(). |
| 138 """ | 140 """ |
| 139 # Make sure we hack subprocess if necessary. | 141 # Make sure we hack subprocess if necessary. |
| 140 hack_subprocess() | 142 hack_subprocess() |
| 141 add_kill() | 143 add_kill() |
| 142 | 144 |
| 143 env = get_english_env(kwargs.get('env')) | 145 env = get_english_env(kwargs.get('env')) |
| 144 if env: | 146 if env: |
| 145 kwargs['env'] = env | 147 kwargs['env'] = env |
| 146 | 148 |
| 147 if not kwargs.get('shell') is None: | 149 if not kwargs.get('shell') is None: |
| 148 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the | 150 # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the |
| 149 # executable, but shell=True makes subprocess on Linux fail when it's called | 151 # executable, but shell=True makes subprocess on Linux fail when it's called |
| 150 # with a list because it only tries to execute the first item in the list. | 152 # with a list because it only tries to execute the first item in the list. |
| 151 kwargs['shell'] = (sys.platform=='win32') | 153 kwargs['shell'] = (sys.platform=='win32') |
| 152 | 154 |
| 153 tmp_str = ' '.join(args) | 155 tmp_str = ' '.join(args) |
| 154 if kwargs.get('cwd', None): | 156 if kwargs.get('cwd', None): |
| 155 tmp_str += '; cwd=%s' % kwargs['cwd'] | 157 tmp_str += '; cwd=%s' % kwargs['cwd'] |
| 156 logging.debug(tmp_str) | 158 logging.debug(tmp_str) |
| 157 | 159 |
| 158 # Replaces VOID with handle to /dev/null. | 160 # Replaces VOID with handle to /dev/null. |
| 159 if kwargs.get('stdout') in (VOID, os.devnull): | 161 if kwargs.get('stdout') in (VOID, os.devnull): |
| 160 kwargs['stdout'] = open(os.devnull, 'w') | 162 kwargs['stdout'] = open(os.devnull, 'w') |
| 161 if kwargs.get('stderr') in (VOID, os.devnull): | 163 if kwargs.get('stderr') in (VOID, os.devnull): |
| 162 kwargs['stderr'] = open(os.devnull, 'w') | 164 kwargs['stderr'] = open(os.devnull, 'w') |
| 163 return subprocess.Popen(args, **kwargs) | 165 try: |
| 166 return subprocess.Popen(args, **kwargs) |
| 167 except OSError, e: |
| 168 if e.errno == errno.EAGAIN and sys.platform == 'cygwin': |
| 169 # Convert fork() emulation failure into a CalledProcessError(). |
| 170 raise CalledProcessError( |
| 171 e.errno, |
| 172 args, |
| 173 kwargs.get('cwd'), |
| 174 'Visit ' |
| 175 'http://code.google.com/p/chromium/wiki/CygwinDllRemappingFailure to ' |
| 176 'learn how to fix this error; you need to rebase your cygwin dlls', |
| 177 None) |
| 178 raise |
| 164 | 179 |
| 165 | 180 |
| 166 def call(args, timeout=None, **kwargs): | 181 def call(args, timeout=None, **kwargs): |
| 167 """Wraps subprocess.Popen().communicate(). | 182 """Wraps subprocess.Popen().communicate(). |
| 168 | 183 |
| 169 Returns ((stdout, stderr), returncode). | 184 Returns ((stdout, stderr), returncode). |
| 170 | 185 |
| 171 - The process will be kill with error code -9 after |timeout| seconds if set. | 186 - The process will be kill with error code -9 after |timeout| seconds if set. |
| 172 - Automatically passes stdin content as input so do not specify stdin=PIPE. | 187 - Automatically passes stdin content as input so do not specify stdin=PIPE. |
| 173 """ | 188 """ |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 | 258 |
| 244 Returns stdout. | 259 Returns stdout. |
| 245 | 260 |
| 246 - Discards stderr. By default sets stderr=STDOUT. | 261 - Discards stderr. By default sets stderr=STDOUT. |
| 247 - Throws if return code is not 0. | 262 - Throws if return code is not 0. |
| 248 - Works even prior to python 2.7. | 263 - Works even prior to python 2.7. |
| 249 """ | 264 """ |
| 250 if kwargs.get('stderr') is None: | 265 if kwargs.get('stderr') is None: |
| 251 kwargs['stderr'] = STDOUT | 266 kwargs['stderr'] = STDOUT |
| 252 return check_call(args, stdout=PIPE, **kwargs)[0] | 267 return check_call(args, stdout=PIPE, **kwargs)[0] |
| OLD | NEW |