pull/1392/head
Alex Willmer 2 weeks ago
parent 2398df1159
commit 5ed1db7991

@ -25,12 +25,6 @@ jobs:
fail-fast: false
matrix:
include:
- tox_env: py27-m_ans-ans2.10
- tox_env: py27-m_ans-ans4
- tox_env: py36-m_ans-ans2.10
- tox_env: py36-m_ans-ans4
- tox_env: py27-m_mtg
- tox_env: py36-m_mtg
@ -86,34 +80,6 @@ jobs:
fail-fast: false
matrix:
include:
- tox_env: py311-m_ans-ans2.10
python_version: '3.11'
- tox_env: py311-m_ans-ans3
python_version: '3.11'
- tox_env: py311-m_ans-ans4
python_version: '3.11'
- tox_env: py311-m_ans-ans5
python_version: '3.11'
- tox_env: py313-m_ans-ans6
python_version: '3.13'
- tox_env: py313-m_ans-ans7
python_version: '3.13'
- tox_env: py313-m_ans-ans8
python_version: '3.13'
- tox_env: py314-m_ans-ans9
python_version: '3.14'
- tox_env: py314-m_ans-ans10
python_version: '3.14'
- tox_env: py314-m_ans-ans11
python_version: '3.14'
- tox_env: py314-m_ans-ans12
python_version: '3.14'
- tox_env: py314-m_ans-ans13
python_version: '3.14'
- tox_env: py314-m_ans-ans13-s_lin
python_version: '3.14'
- tox_env: py314-m_mtg
python_version: '3.14'
@ -161,11 +127,6 @@ jobs:
fail-fast: false
matrix:
include:
- tox_env: py314-m_lcl-ans13
python_version: '3.14'
- tox_env: py314-m_lcl-ans13-s_lin
python_version: '3.14'
- tox_env: py314-m_mtg
python_version: '3.14'

@ -1415,11 +1415,11 @@ class Connection(object):
# W: write side of interpreter stdin.
# r: read side of core_src FD.
# w: write side of core_src FD.
# Final os.close(STDOUT_FILENO) to avoid --py-debug build corrupting stream with
# "[1234 refs]" during exit.
@staticmethod
def _first_stage():
# Bail out in case STDIN or STDOUT is not accessible (e.g. closed)
#os.fstat(0)
#os.fstat(1)
R,W=os.pipe()
r,w=os.pipe()
if os.fork():
@ -1436,11 +1436,16 @@ class Connection(object):
os.environ['ARGV0']=sys.executable
os.execl(sys.executable,sys.executable+'(mitogen:%s)'%sys.argv[2])
os.write(1,'MITO000\n'.encode())
# size of the compressed core source to be read
n=int(sys.argv[3])
# Read `len(compressed preamble)` bytes sent by our Mitogen parent.
# `select()` handles non-blocking stdin (e.g. sudo + log_output).
# `C` accumulates compressed bytes.
C=''.encode()
while int(sys.argv[3])-len(C)and select.select([0],[],[]):C+=os.read(0,int(sys.argv[3])-len(C))
# data chunk
V='V'
# Stop looping if no more data is needed or EOF is detected (empty bytes).
while n-len(C) and V:select.select([0],[],[]);V=os.read(0,n-len(C));C+=V
# Raises `zlib.error` if compressed preamble is truncated or invalid
C=zlib.decompress(C)
f=os.fdopen(W,'wb',0)
@ -1450,6 +1455,10 @@ class Connection(object):
f.write(C)
f.close()
os.write(1,'MITO001\n'.encode())
# Final os.close(STDERR_FILENO) to avoid `--py-debug` build corrupting
# stream with "[1234 refs]" during exit.
# If STDERR is already closed an OSError is raised, but no one cares
# as STDERR is closed and the exit status is not forwarded.
os.close(2)
def get_python_argv(self):

@ -50,3 +50,39 @@ class CommandLineTest(testlib.RouterMixin, testlib.TestCase):
)
finally:
fp.close()
def test_premature_eof(self):
options = mitogen.parent.Options(max_message_size=123)
conn = mitogen.parent.Connection(options, self.router)
conn.context = mitogen.core.Context(None, 123)
proc = testlib.subprocess.Popen(
args=conn.get_boot_command(),
stdout=testlib.subprocess.PIPE,
stderr=testlib.subprocess.PIPE,
stdin=testlib.subprocess.PIPE,
)
# Do not send all of the data from the preamble
proc.stdin.write(conn.get_preamble()[:-128])
proc.stdin.flush() # XXX Is this redundant? Does close() alwys flush()?
proc.stdin.close()
try:
returncode = proc.wait(timeout=10)
except testlib.subprocess.TimeoutExpired:
proc.kill()
proc.wait(timeout=3)
self.fail("First stage did not handle EOF on STDIN")
try:
self.assertEqual(0, returncode)
self.assertEqual(
proc.stdout.read(),
mitogen.parent.BootstrapProtocol.EC0_MARKER + b("\n"),
)
self.assertIn(
b("Error -5 while decompressing data"),
proc.stderr.read(),
)
finally:
proc.stdout.close()
proc.stderr.close()

Loading…
Cancel
Save