1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

lit: When executing shell scripts internally, don't allow piped stderr on any

commands except the last one, instead redirect the stderr to a temporary
file. This sidesteps a potential deadlocking issue.

llvm-svn: 82538
This commit is contained in:
Daniel Dunbar 2009-09-22 09:50:38 +00:00
parent 06695b3ea1
commit b8a623820a

View File

@ -6,6 +6,7 @@ import Test
import Util
import platform
import tempfile
class InternalShellError(Exception):
def __init__(self, command, message):
@ -57,7 +58,11 @@ def executeShCmd(cmd, cfg, cwd, results):
assert isinstance(cmd, ShUtil.Pipeline)
procs = []
input = subprocess.PIPE
for j in cmd.commands:
stderrTempFiles = []
# To avoid deadlock, we use a single stderr stream for piped
# output. This is null until we have seen some output using
# stderr.
for i,j in enumerate(cmd.commands):
redirects = [(0,), (1,), (2,)]
for r in j.redirects:
if r[0] == ('>',2):
@ -104,6 +109,14 @@ def executeShCmd(cmd, cfg, cwd, results):
else:
stderrIsStdout = False
# Don't allow stderr on a PIPE except for the last
# process, this could deadlock.
#
# FIXME: This is slow, but so is deadlock.
if stderr == subprocess.PIPE and j != cmd.commands[-1]:
stderr = tempfile.TemporaryFile(mode='w+b')
stderrTempFiles.append((i, stderr))
# Resolve the executable path ourselves.
args = list(j.args)
args[0] = Util.which(args[0], cfg.environment['PATH'])
@ -130,10 +143,10 @@ def executeShCmd(cmd, cfg, cwd, results):
else:
input = subprocess.PIPE
# FIXME: There is a potential for deadlock here, when we have a pipe and
# some process other than the last one ends up blocked on stderr.
# FIXME: There is probably still deadlock potential here. Yawn.
procData = [None] * len(procs)
procData[-1] = procs[-1].communicate()
for i in range(len(procs) - 1):
if procs[i].stdout is not None:
out = procs[i].stdout.read()
@ -144,6 +157,11 @@ def executeShCmd(cmd, cfg, cwd, results):
else:
err = ''
procData[i] = (out,err)
# Read stderr out of the temp files.
for i,f in stderrTempFiles:
f.seek(0, 0)
procData[i] = (procData[i][0], f.read())
exitCode = None
for i,(out,err) in enumerate(procData):