diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2011-07-05 12:08:01 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2011-07-05 12:08:01 (GMT) |
commit | e790131dc6f2e4c125f29c882e64f3c88a4210d1 (patch) | |
tree | 7440e0e559e78000a3ce242aabaab4209ebd86be | |
parent | 4c41f84033ed257b3ef6586acd12ff87d00fa323 (diff) | |
download | cpython-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.py | 6 | ||||
-rw-r--r-- | Lib/test/test_subprocess.py | 16 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
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): @@ -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. |