@ -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 ) :