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