summaryrefslogtreecommitdiff
path: root/Lib/subprocess.py
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2012-11-10 22:49:03 -0800
committerGregory P. Smith <greg@krypto.org>2012-11-10 22:49:03 -0800
commit9d3b6e9822334a918b0130b23a44a467f40fdb42 (patch)
tree3c77b7c83c32e3396becba969c086372392307c9 /Lib/subprocess.py
parentf2705aebb04a1c3f758d7f3383b981e1673525b7 (diff)
downloadcpython-git-9d3b6e9822334a918b0130b23a44a467f40fdb42.tar.gz
Fixes issue #16327: The subprocess module no longer leaks file descriptors
used for stdin/stdout/stderr pipes to the child when fork() fails.
Diffstat (limited to 'Lib/subprocess.py')
-rw-r--r--Lib/subprocess.py33
1 files changed, 27 insertions, 6 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 8356782224..d1377d3b04 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -671,12 +671,33 @@ class Popen(object):
c2pread, c2pwrite,
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
- self._execute_child(args, executable, preexec_fn, close_fds,
- cwd, env, universal_newlines,
- startupinfo, creationflags, shell,
- p2cread, p2cwrite,
- c2pread, c2pwrite,
- errread, errwrite)
+ try:
+ self._execute_child(args, executable, preexec_fn, close_fds,
+ cwd, env, universal_newlines,
+ startupinfo, creationflags, shell,
+ p2cread, p2cwrite,
+ c2pread, c2pwrite,
+ errread, errwrite)
+ except Exception:
+ # Preserve original exception in case os.close raises.
+ exc_type, exc_value, exc_trace = sys.exc_info()
+
+ to_close = []
+ # Only close the pipes we created.
+ if stdin == PIPE:
+ to_close.extend((p2cread, p2cwrite))
+ if stdout == PIPE:
+ to_close.extend((c2pread, c2pwrite))
+ if stderr == PIPE:
+ to_close.extend((errread, errwrite))
+
+ for fd in to_close:
+ try:
+ os.close(fd)
+ except EnvironmentError:
+ pass
+
+ raise exc_type, exc_value, exc_trace
if mswindows:
if p2cwrite is not None: