prevent deadlock from filling buffer

This commit is contained in:
adam j hartz 2016-05-12 21:48:33 -04:00
parent 520fb2dcab
commit 28562f19e8

View file

@ -421,13 +421,17 @@ def run_subproc(cmds, captured=False):
elif prev_proc is not None: elif prev_proc is not None:
stdin = prev_proc.stdout stdin = prev_proc.stdout
# set standard output # set standard output
_stdout_name = None
_stderr_name = None
if 'stdout' in streams: if 'stdout' in streams:
if ix != last_cmd: if ix != last_cmd:
raise XonshError('Multiple redirects for stdout') raise XonshError('Multiple redirects for stdout')
stdout = streams['stdout'][-1] stdout = streams['stdout'][-1]
procinfo['stdout_redirect'] = streams['stdout'][:-1] procinfo['stdout_redirect'] = streams['stdout'][:-1]
elif _capture_streams or ix != last_cmd: elif _capture_streams or ix != last_cmd:
stdout = PIPE _stdout = tempfile.NamedTemporaryFile(delete=False)
_stdout_name = _stdout.name
stdout = open(_stdout_name, 'w')
elif builtins.__xonsh_stdout_uncaptured__ is not None: elif builtins.__xonsh_stdout_uncaptured__ is not None:
stdout = builtins.__xonsh_stdout_uncaptured__ stdout = builtins.__xonsh_stdout_uncaptured__
else: else:
@ -437,7 +441,9 @@ def run_subproc(cmds, captured=False):
stderr = streams['stderr'][-1] stderr = streams['stderr'][-1]
procinfo['stderr_redirect'] = streams['stderr'][:-1] procinfo['stderr_redirect'] = streams['stderr'][:-1]
elif captured == 'object': elif captured == 'object':
stderr = PIPE _stderr = tempfile.NamedTemporaryFile(delete=False)
_stderr_name = _stderr.name
stderr = open(_stderr_name, 'w')
elif builtins.__xonsh_stderr_uncaptured__ is not None: elif builtins.__xonsh_stderr_uncaptured__ is not None:
stderr = builtins.__xonsh_stderr_uncaptured__ stderr = builtins.__xonsh_stderr_uncaptured__
uninew = (ix == last_cmd) and (not _capture_streams) uninew = (ix == last_cmd) and (not _capture_streams)
@ -552,7 +558,13 @@ def run_subproc(cmds, captured=False):
# get output # get output
output = b'' output = b''
if write_target is None: if write_target is None:
if prev_proc.stdout not in (None, sys.stdout): if _stdout_name is not None:
stdout = open(_stdout_name, 'rb')
stdout.seek(0)
output = stdout.read()
stdout.close()
os.unlink(_stdout_name)
elif prev_proc.stdout not in (None, sys.stdout):
output = prev_proc.stdout.read() output = prev_proc.stdout.read()
if _capture_streams: if _capture_streams:
# to get proper encoding from Popen, we have to # to get proper encoding from Popen, we have to
@ -562,9 +574,18 @@ def run_subproc(cmds, captured=False):
output = output.replace('\r\n', '\n') output = output.replace('\r\n', '\n')
else: else:
hist.last_cmd_out = output hist.last_cmd_out = output
if (captured == 'object' and if captured == 'object': # get stderr as well
prev_proc.stderr not in {None, sys.stderr}): named = _stderr_name is not None
unnamed = prev_proc.stderr not in {None, sys.stderr}
if named:
stderr = open(_stderr_name, 'rb')
stderr.seek(0)
errout = stderr.read()
stderr.close()
os.unlink(_stderr_name)
elif unnamed:
errout = prev_proc.stderr.read() errout = prev_proc.stderr.read()
if named or unnamed:
errout = errout.decode(encoding=ENV.get('XONSH_ENCODING'), errout = errout.decode(encoding=ENV.get('XONSH_ENCODING'),
errors=ENV.get('XONSH_ENCODING_ERRORS')) errors=ENV.get('XONSH_ENCODING_ERRORS'))
errout = errout.replace('\r\n', '\n') errout = errout.replace('\r\n', '\n')