mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82538 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
df3388492b
commit
5a461dd513
@ -6,6 +6,7 @@ import Test
|
|||||||
import Util
|
import Util
|
||||||
|
|
||||||
import platform
|
import platform
|
||||||
|
import tempfile
|
||||||
|
|
||||||
class InternalShellError(Exception):
|
class InternalShellError(Exception):
|
||||||
def __init__(self, command, message):
|
def __init__(self, command, message):
|
||||||
@ -57,7 +58,11 @@ def executeShCmd(cmd, cfg, cwd, results):
|
|||||||
assert isinstance(cmd, ShUtil.Pipeline)
|
assert isinstance(cmd, ShUtil.Pipeline)
|
||||||
procs = []
|
procs = []
|
||||||
input = subprocess.PIPE
|
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,)]
|
redirects = [(0,), (1,), (2,)]
|
||||||
for r in j.redirects:
|
for r in j.redirects:
|
||||||
if r[0] == ('>',2):
|
if r[0] == ('>',2):
|
||||||
@ -104,6 +109,14 @@ def executeShCmd(cmd, cfg, cwd, results):
|
|||||||
else:
|
else:
|
||||||
stderrIsStdout = False
|
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.
|
# Resolve the executable path ourselves.
|
||||||
args = list(j.args)
|
args = list(j.args)
|
||||||
args[0] = Util.which(args[0], cfg.environment['PATH'])
|
args[0] = Util.which(args[0], cfg.environment['PATH'])
|
||||||
@ -130,10 +143,10 @@ def executeShCmd(cmd, cfg, cwd, results):
|
|||||||
else:
|
else:
|
||||||
input = subprocess.PIPE
|
input = subprocess.PIPE
|
||||||
|
|
||||||
# FIXME: There is a potential for deadlock here, when we have a pipe and
|
# FIXME: There is probably still deadlock potential here. Yawn.
|
||||||
# some process other than the last one ends up blocked on stderr.
|
|
||||||
procData = [None] * len(procs)
|
procData = [None] * len(procs)
|
||||||
procData[-1] = procs[-1].communicate()
|
procData[-1] = procs[-1].communicate()
|
||||||
|
|
||||||
for i in range(len(procs) - 1):
|
for i in range(len(procs) - 1):
|
||||||
if procs[i].stdout is not None:
|
if procs[i].stdout is not None:
|
||||||
out = procs[i].stdout.read()
|
out = procs[i].stdout.read()
|
||||||
@ -144,6 +157,11 @@ def executeShCmd(cmd, cfg, cwd, results):
|
|||||||
else:
|
else:
|
||||||
err = ''
|
err = ''
|
||||||
procData[i] = (out,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
|
exitCode = None
|
||||||
for i,(out,err) in enumerate(procData):
|
for i,(out,err) in enumerate(procData):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user