summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2011-07-05 12:08:01 (GMT)
committerVictor Stinner <victor.stinner@haypocalc.com>2011-07-05 12:08:01 (GMT)
commite790131dc6f2e4c125f29c882e64f3c88a4210d1 (patch)
tree7440e0e559e78000a3ce242aabaab4209ebd86be
parent4c41f84033ed257b3ef6586acd12ff87d00fa323 (diff)
downloadcpython-e790131dc6f2e4c125f29c882e64f3c88a4210d1.zip
cpython-e790131dc6f2e4c125f29c882e64f3c88a4210d1.tar.gz
cpython-e790131dc6f2e4c125f29c882e64f3c88a4210d1.tar.bz2
Issue #12493: subprocess: communicate() handles EINTR
subprocess.Popen.communicate() now also handles EINTR errors if the process has only one pipe.
-rw-r--r--Lib/subprocess.py6
-rw-r--r--Lib/test/test_subprocess.py16
-rw-r--r--Misc/NEWS3
3 files changed, 22 insertions, 3 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index bdf85fc..ce08f83 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -476,7 +476,7 @@ def _eintr_retry_call(func, *args):
while True:
try:
return func(*args)
- except OSError, e:
+ except (OSError, IOError) as e:
if e.errno == errno.EINTR:
continue
raise
@@ -743,10 +743,10 @@ class Popen(object):
raise
self.stdin.close()
elif self.stdout:
- stdout = self.stdout.read()
+ stdout = _eintr_retry_call(self.stdout.read)
self.stdout.close()
elif self.stderr:
- stderr = self.stderr.read()
+ stderr = _eintr_retry_call(self.stderr.read)
self.stderr.close()
self.wait()
return (stdout, stderr)
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index a93602a..a17f2f7 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -664,6 +664,22 @@ class _SuppressCoreFiles(object):
except (ImportError, ValueError, resource.error):
pass
+ 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()
+
@unittest.skipIf(mswindows, "POSIX specific tests")
class POSIXProcessTestCase(BaseTestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
index 38dff5b..d062d10 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -21,6 +21,9 @@ Core and Builtins
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
shutdown, if globals()['__file__'] is None.