| Index: subprocess2.py
|
| diff --git a/subprocess2.py b/subprocess2.py
|
| index afe5c75c17122b289c1a36acf1c8ddeeb3d28ca3..3b48137988c3b2c529520940f0975d5a7ef7dbf3 100644
|
| --- a/subprocess2.py
|
| +++ b/subprocess2.py
|
| @@ -131,11 +131,9 @@ def get_english_env(env):
|
| return env
|
|
|
|
|
| -def Popen(args, **kwargs):
|
| +class Popen(subprocess.Popen):
|
| """Wraps subprocess.Popen() with various workarounds.
|
|
|
| - Returns a subprocess.Popen object.
|
| -
|
| - Forces English output since it's easier to parse the stdout if it is always
|
| in English.
|
| - Sets shell=True on windows by default. You can override this by forcing
|
| @@ -145,57 +143,60 @@ def Popen(args, **kwargs):
|
| Note: Popen() can throw OSError when cwd or args[0] doesn't exist. Translate
|
| exceptions generated by cygwin when it fails trying to emulate fork().
|
| """
|
| - # Make sure we hack subprocess if necessary.
|
| - hack_subprocess()
|
| - add_kill()
|
| -
|
| - env = get_english_env(kwargs.get('env'))
|
| - if env:
|
| - kwargs['env'] = env
|
| - if kwargs.get('shell') is None:
|
| - # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for the
|
| - # executable, but shell=True makes subprocess on Linux fail when it's called
|
| - # with a list because it only tries to execute the first item in the list.
|
| - kwargs['shell'] = bool(sys.platform=='win32')
|
| -
|
| - if isinstance(args, basestring):
|
| - tmp_str = args
|
| - elif isinstance(args, (list, tuple)):
|
| - tmp_str = ' '.join(args)
|
| - else:
|
| - raise CalledProcessError(None, args, kwargs.get('cwd'), None, None)
|
| - if kwargs.get('cwd', None):
|
| - tmp_str += '; cwd=%s' % kwargs['cwd']
|
| - logging.debug(tmp_str)
|
| -
|
| - def fix(stream):
|
| - if kwargs.get(stream) in (VOID, os.devnull):
|
| - # Replaces VOID with handle to /dev/null.
|
| - # Create a temporary file to workaround python's deadlock.
|
| - # http://docs.python.org/library/subprocess.html#subprocess.Popen.wait
|
| - # When the pipe fills up, it will deadlock this process. Using a real file
|
| - # works around that issue.
|
| - kwargs[stream] = open(os.devnull, 'w')
|
| -
|
| - fix('stdout')
|
| - fix('stderr')
|
| -
|
| - try:
|
| - return subprocess.Popen(args, **kwargs)
|
| - except OSError, e:
|
| - if e.errno == errno.EAGAIN and sys.platform == 'cygwin':
|
| - # Convert fork() emulation failure into a CygwinRebaseError().
|
| - raise CygwinRebaseError(
|
| - e.errno,
|
| - args,
|
| - kwargs.get('cwd'),
|
| - None,
|
| - 'Visit '
|
| - 'http://code.google.com/p/chromium/wiki/CygwinDllRemappingFailure to '
|
| - 'learn how to fix this error; you need to rebase your cygwin dlls')
|
| - # Popen() can throw OSError when cwd or args[0] doesn't exist. Let it go
|
| - # through
|
| - raise
|
| + def __init__(self, args, **kwargs):
|
| + # Make sure we hack subprocess if necessary.
|
| + hack_subprocess()
|
| + add_kill()
|
| +
|
| + env = get_english_env(kwargs.get('env'))
|
| + if env:
|
| + kwargs['env'] = env
|
| + if kwargs.get('shell') is None:
|
| + # *Sigh*: Windows needs shell=True, or else it won't search %PATH% for
|
| + # the executable, but shell=True makes subprocess on Linux fail when it's
|
| + # called with a list because it only tries to execute the first item in
|
| + # the list.
|
| + kwargs['shell'] = bool(sys.platform=='win32')
|
| +
|
| + if isinstance(args, basestring):
|
| + tmp_str = args
|
| + elif isinstance(args, (list, tuple)):
|
| + tmp_str = ' '.join(args)
|
| + else:
|
| + raise CalledProcessError(None, args, kwargs.get('cwd'), None, None)
|
| + if kwargs.get('cwd', None):
|
| + tmp_str += '; cwd=%s' % kwargs['cwd']
|
| + logging.debug(tmp_str)
|
| +
|
| + def fix(stream):
|
| + if kwargs.get(stream) in (VOID, os.devnull):
|
| + # Replaces VOID with handle to /dev/null.
|
| + # Create a temporary file to workaround python's deadlock.
|
| + # http://docs.python.org/library/subprocess.html#subprocess.Popen.wait
|
| + # When the pipe fills up, it will deadlock this process. Using a real
|
| + # file works around that issue.
|
| + kwargs[stream] = open(os.devnull, 'w')
|
| +
|
| + fix('stdout')
|
| + fix('stderr')
|
| +
|
| + try:
|
| + super(Popen, self).__init__(args, **kwargs)
|
| + except OSError, e:
|
| + if e.errno == errno.EAGAIN and sys.platform == 'cygwin':
|
| + # Convert fork() emulation failure into a CygwinRebaseError().
|
| + raise CygwinRebaseError(
|
| + e.errno,
|
| + args,
|
| + kwargs.get('cwd'),
|
| + None,
|
| + 'Visit '
|
| + 'http://code.google.com/p/chromium/wiki/CygwinDllRemappingFailure '
|
| + 'to learn how to fix this error; you need to rebase your cygwin '
|
| + 'dlls')
|
| + # Popen() can throw OSError when cwd or args[0] doesn't exist. Let it go
|
| + # through
|
| + raise
|
|
|
|
|
| def communicate(args, timeout=None, **kwargs):
|
|
|