Skip to content

Commit bafa848

Browse files
giampaologpshead
authored andcommitted
subprocess: close pipes/fds by using ExitStack (GH-11686)
Close pipes/fds in subprocess by using ExitStack. "In case of premature failure on X.Close() or os.close(X) the remaining pipes/fds will remain "open". Perhaps it makes sense to use contextlib.ExitStack." - Rationale: #11575 (comment)
1 parent 742d768 commit bafa848

File tree

2 files changed

+22
-17
lines changed

2 files changed

+22
-17
lines changed

Lib/subprocess.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import sys
5151
import threading
5252
import warnings
53+
import contextlib
5354
from time import monotonic as _time
5455

5556

@@ -1072,28 +1073,28 @@ def _close_pipe_fds(self,
10721073
# self._devnull is not always defined.
10731074
devnull_fd = getattr(self, '_devnull', None)
10741075

1075-
if _mswindows:
1076-
if p2cread != -1:
1077-
p2cread.Close()
1078-
if c2pwrite != -1:
1079-
c2pwrite.Close()
1080-
if errwrite != -1:
1081-
errwrite.Close()
1082-
else:
1083-
if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd:
1084-
os.close(p2cread)
1085-
if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd:
1086-
os.close(c2pwrite)
1087-
if errwrite != -1 and errread != -1 and errwrite != devnull_fd:
1088-
os.close(errwrite)
1076+
with contextlib.ExitStack() as stack:
1077+
if _mswindows:
1078+
if p2cread != -1:
1079+
stack.callback(p2cread.Close)
1080+
if c2pwrite != -1:
1081+
stack.callback(c2pwrite.Close)
1082+
if errwrite != -1:
1083+
stack.callback(errwrite.Close)
1084+
else:
1085+
if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd:
1086+
stack.callback(os.close, p2cread)
1087+
if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd:
1088+
stack.callback(os.close, c2pwrite)
1089+
if errwrite != -1 and errread != -1 and errwrite != devnull_fd:
1090+
stack.callback(os.close, errwrite)
10891091

1090-
if devnull_fd is not None:
1091-
os.close(devnull_fd)
1092+
if devnull_fd is not None:
1093+
stack.callback(os.close, devnull_fd)
10921094

10931095
# Prevent a double close of these handles/fds from __init__ on error.
10941096
self._closed_child_pipe_fds = True
10951097

1096-
10971098
if _mswindows:
10981099
#
10991100
# Windows methods
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
An ExitStack is now used internally within subprocess.POpen to clean up pipe
2+
file handles. No behavior change in normal operation. But if closing one
3+
handle were ever to cause an exception, the others will now be closed
4+
instead of leaked. (patch by Giampaolo Rodola)

0 commit comments

Comments
 (0)