Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit af5ac39

Browse files
committed
Issue #3210: Ensure stdio handles are closed if CreateProcess fails
1 parent 2e3d539 commit af5ac39

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

Lib/test/test_subprocess.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,26 @@ def test_issue8780(self):
544544
output = subprocess.check_output([sys.executable, '-c', code])
545545
self.assert_(output.startswith(b'Hello World!'), ascii(output))
546546

547+
def test_handles_closed_on_exception(self):
548+
# If CreateProcess exits with an error, ensure the
549+
# duplicate output handles are released
550+
ifhandle, ifname = mkstemp()
551+
ofhandle, ofname = mkstemp()
552+
efhandle, efname = mkstemp()
553+
try:
554+
subprocess.Popen (["*"], stdin=ifhandle, stdout=ofhandle,
555+
stderr=efhandle)
556+
except OSError:
557+
os.close(ifhandle)
558+
os.remove(ifname)
559+
os.close(ofhandle)
560+
os.remove(ofname)
561+
os.close(efhandle)
562+
os.remove(efname)
563+
self.assertFalse(os.path.exists(ifname))
564+
self.assertFalse(os.path.exists(ofname))
565+
self.assertFalse(os.path.exists(efname))
566+
547567

548568
# context manager
549569
class _SuppressCoreFiles(object):

PC/_subprocess.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ sp_CreateProcess(PyObject* self, PyObject* args)
429429
PyObject* env_mapping;
430430
Py_UNICODE* current_directory;
431431
PyObject* startup_info;
432+
DWORD error;
432433

433434
if (! PyArg_ParseTuple(args, "ZZOOiiOZO:CreateProcess",
434435
&application_name,
@@ -478,8 +479,22 @@ sp_CreateProcess(PyObject* self, PyObject* args)
478479

479480
Py_XDECREF(environment);
480481

481-
if (! result)
482-
return PyErr_SetFromWindowsErr(GetLastError());
482+
if (! result) {
483+
error = GetLastError();
484+
if(si.hStdInput != INVALID_HANDLE_VALUE) {
485+
CloseHandle(si.hStdInput);
486+
si.hStdInput = INVALID_HANDLE_VALUE;
487+
}
488+
if(si.hStdOutput != INVALID_HANDLE_VALUE) {
489+
CloseHandle(si.hStdOutput);
490+
si.hStdOutput = INVALID_HANDLE_VALUE;
491+
}
492+
if(si.hStdError != INVALID_HANDLE_VALUE) {
493+
CloseHandle(si.hStdError);
494+
si.hStdError = INVALID_HANDLE_VALUE;
495+
}
496+
return PyErr_SetFromWindowsErr(error);
497+
}
483498

484499
return Py_BuildValue("NNii",
485500
sp_handle_new(pi.hProcess),

0 commit comments

Comments
 (0)