Skip to content

Commit f8dc3e8

Browse files
bpo-37549: os.dup() fails for standard streams on Windows 7 (GH-15389)
(cherry picked from commit 5be6660) Co-authored-by: Zackery Spytz <zspytz@gmail.com>
1 parent 8fac472 commit f8dc3e8

3 files changed

Lines changed: 14 additions & 1 deletion

File tree

Lib/test/test_os.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3237,6 +3237,11 @@ def test_dup(self):
32373237
self.addCleanup(os.close, fd2)
32383238
self.assertEqual(os.get_inheritable(fd2), False)
32393239

3240+
def test_dup_standard_stream(self):
3241+
fd = os.dup(1)
3242+
self.addCleanup(os.close, fd)
3243+
self.assertGreater(fd, 0)
3244+
32403245
@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
32413246
def test_dup_nul(self):
32423247
# os.dup() was creating inheritable fds for character files.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:func:`os.dup` no longer fails for standard streams on Windows 7.

Python/fileutils.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,11 +1037,18 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
10371037
flags = HANDLE_FLAG_INHERIT;
10381038
else
10391039
flags = 0;
1040-
if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
1040+
1041+
/* This check can be removed once support for Windows 7 ends. */
1042+
#define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \
1043+
GetFileType(handle) == FILE_TYPE_CHAR)
1044+
1045+
if (!CONSOLE_PSEUDOHANDLE(handle) &&
1046+
!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
10411047
if (raise)
10421048
PyErr_SetFromWindowsErr(0);
10431049
return -1;
10441050
}
1051+
#undef CONSOLE_PSEUDOHANDLE
10451052
return 0;
10461053

10471054
#else

0 commit comments

Comments
 (0)