Skip to content

Commit ac73a01

Browse files
author
hirokazu.yamamoto
committed
Merged revisions 70137 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r70137 | hirokazu.yamamoto | 2009-03-04 07:18:14 +0900 | 1 line Issue #5179: Fixed subprocess handle leak on failure on windows. ........ git-svn-id: http://svn.python.org/projects/python/branches/py3k@70142 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 1136a7f commit ac73a01

3 files changed

Lines changed: 18 additions & 33 deletions

File tree

Lib/subprocess.py

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -638,21 +638,13 @@ def __init__(self, args, bufsize=0, executable=None,
638638
c2pread, c2pwrite,
639639
errread, errwrite)
640640

641-
# On Windows, you cannot just redirect one or two handles: You
642-
# either have to redirect all three or none. If the subprocess
643-
# user has only redirected one or two handles, we are
644-
# automatically creating PIPEs for the rest. We should close
645-
# these after the process is started. See bug #1124861.
646641
if mswindows:
647-
if stdin is None and p2cwrite is not None:
648-
os.close(p2cwrite)
649-
p2cwrite = None
650-
if stdout is None and c2pread is not None:
651-
os.close(c2pread)
652-
c2pread = None
653-
if stderr is None and errread is not None:
654-
os.close(errread)
655-
errread = None
642+
if p2cwrite is not None:
643+
p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0)
644+
if c2pread is not None:
645+
c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0)
646+
if errread is not None:
647+
errread = msvcrt.open_osfhandle(errread.Detach(), 0)
656648

657649
if bufsize == 0:
658650
bufsize = 1 # Nearly unbuffered (XXX for now)
@@ -737,13 +729,10 @@ def _get_handles(self, stdin, stdout, stderr):
737729

738730
if stdin is None:
739731
p2cread = GetStdHandle(STD_INPUT_HANDLE)
740-
if p2cread is not None:
741-
pass
742-
elif stdin is None or stdin == PIPE:
732+
if p2cread is None:
733+
p2cread, _ = CreatePipe(None, 0)
734+
elif stdin == PIPE:
743735
p2cread, p2cwrite = CreatePipe(None, 0)
744-
# Detach and turn into fd
745-
p2cwrite = p2cwrite.Detach()
746-
p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0)
747736
elif isinstance(stdin, int):
748737
p2cread = msvcrt.get_osfhandle(stdin)
749738
else:
@@ -753,13 +742,10 @@ def _get_handles(self, stdin, stdout, stderr):
753742

754743
if stdout is None:
755744
c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE)
756-
if c2pwrite is not None:
757-
pass
758-
elif stdout is None or stdout == PIPE:
745+
if c2pwrite is None:
746+
_, c2pwrite = CreatePipe(None, 0)
747+
elif stdout == PIPE:
759748
c2pread, c2pwrite = CreatePipe(None, 0)
760-
# Detach and turn into fd
761-
c2pread = c2pread.Detach()
762-
c2pread = msvcrt.open_osfhandle(c2pread, 0)
763749
elif isinstance(stdout, int):
764750
c2pwrite = msvcrt.get_osfhandle(stdout)
765751
else:
@@ -769,13 +755,10 @@ def _get_handles(self, stdin, stdout, stderr):
769755

770756
if stderr is None:
771757
errwrite = GetStdHandle(STD_ERROR_HANDLE)
772-
if errwrite is not None:
773-
pass
774-
elif stderr is None or stderr == PIPE:
758+
if errwrite is None:
759+
_, errwrite = CreatePipe(None, 0)
760+
elif stderr == PIPE:
775761
errread, errwrite = CreatePipe(None, 0)
776-
# Detach and turn into fd
777-
errread = errread.Detach()
778-
errread = msvcrt.open_osfhandle(errread, 0)
779762
elif stderr == STDOUT:
780763
errwrite = c2pwrite
781764
elif isinstance(stderr, int):

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ Core and Builtins
181181
Library
182182
-------
183183

184+
- Issue #5179: Fixed subprocess handle leak on failure on windows.
185+
184186
- PEP 372: Added collections.OrderedDict().
185187

186188
- The _asdict() for method for namedtuples now returns an OrderedDict().

PC/_subprocess.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ sp_handle_detach(sp_handle_object* self, PyObject* args)
8484

8585
handle = self->handle;
8686

87-
self->handle = NULL;
87+
self->handle = INVALID_HANDLE_VALUE;
8888

8989
/* note: return the current handle, as an integer */
9090
return HANDLE_TO_PYNUM(handle);

0 commit comments

Comments
 (0)