Commit 5b1261d7 authored by Victor Stinner's avatar Victor Stinner

(merge 3.2) Issue #12493: subprocess: communicate() handles EINTR

subprocess.Popen.communicate() now also handles EINTR errors if the process has
only one pipe.
parents d9fc85db 2cfb6f3a
...@@ -446,7 +446,7 @@ def _eintr_retry_call(func, *args): ...@@ -446,7 +446,7 @@ def _eintr_retry_call(func, *args):
while True: while True:
try: try:
return func(*args) return func(*args)
except OSError as e: except (OSError, IOError) as e:
if e.errno == errno.EINTR: if e.errno == errno.EINTR:
continue continue
raise raise
...@@ -820,10 +820,10 @@ class Popen(object): ...@@ -820,10 +820,10 @@ class Popen(object):
raise raise
self.stdin.close() self.stdin.close()
elif self.stdout: elif self.stdout:
stdout = self.stdout.read() stdout = _eintr_retry_call(self.stdout.read)
self.stdout.close() self.stdout.close()
elif self.stderr: elif self.stderr:
stderr = self.stderr.read() stderr = _eintr_retry_call(self.stderr.read)
self.stderr.close() self.stderr.close()
self.wait() self.wait()
else: else:
......
...@@ -767,6 +767,22 @@ class ProcessTestCase(BaseTestCase): ...@@ -767,6 +767,22 @@ class ProcessTestCase(BaseTestCase):
time.sleep(2) time.sleep(2)
p.communicate(b"x" * 2**20) p.communicate(b"x" * 2**20)
def test_communicate_eintr(self):
# Issue #12493: communicate() should handle EINTR
def handler(signum, frame):
pass
old_handler = signal.signal(signal.SIGALRM, handler)
self.addCleanup(signal.signal, signal.SIGALRM, old_handler)
# the process is running for 2 seconds
args = [sys.executable, "-c", 'import time; time.sleep(2)']
for stream in ('stdout', 'stderr'):
kw = {stream: subprocess.PIPE}
with subprocess.Popen(args, **kw) as process:
signal.alarm(1)
# communicate() will be interrupted by SIGALRM
process.communicate()
# context manager # context manager
class _SuppressCoreFiles(object): class _SuppressCoreFiles(object):
......
...@@ -219,6 +219,9 @@ Core and Builtins ...@@ -219,6 +219,9 @@ Core and Builtins
Library Library
------- -------
- Issue #12493: subprocess: Popen.communicate() now also handles EINTR errors
if the process has only one pipe.
- Issue #12467: warnings: fix a race condition if a warning is emitted at - Issue #12467: warnings: fix a race condition if a warning is emitted at
shutdown, if globals()['__file__'] is None. shutdown, if globals()['__file__'] is None.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment