Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -4485,6 +4485,55 @@ def test_openpty(self):
self.assertEqual(os.get_inheritable(master_fd), False)
self.assertEqual(os.get_inheritable(slave_fd), False)

@unittest.skipUnless(hasattr(os, 'spawnl'), "need os.openpty()")
def test_pipe_spawnl(self):
# gh-77046: On Windows, os.pipe() file descriptors must be created with
# _O_NOINHERIT to make them non-inheritable. UCRT has no public API to
# get (_osfile(fd) & _O_NOINHERIT), so use a functional test.
fd, fd2 = os.pipe()
self.addCleanup(os.close, fd)
self.addCleanup(os.close, fd2)

# Make sure that fd is not inherited by a child process created by
# os.spawnl(): get_osfhandle() and dup() must fail with EBADF.
code = textwrap.dedent(f"""
import errno
import os
try:
import msvcrt
except ImportError:
msvcrt = None

fd = {fd}

if msvcrt is not None:
try:
handle = msvcrt.get_osfhandle(fd)
except OSError as exc:
if exc.errno != errno.EBADF:
raise
else:
raise Exception("get_osfhandle() must fail")

try:
fd3 = os.dup(fd)
except OSError as exc:
if exc.errno != errno.EBADF:
raise
else:
os.close(fd3)
raise Exception("dup must fail")
""")

filename = os_helper.TESTFN
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
with open(filename, "w") as fp:
print(code, file=fp, end="")

cmd = [sys.executable, filename]
exitcode = os.spawnl(os.P_WAIT, cmd[0], *cmd)
self.assertEqual(exitcode, 0)


class PathTConverterTests(unittest.TestCase):
# tuples of (function name, allows fd arguments, additional arguments to
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
On Windows, file descriptors wrapping Windows handles are now created non
inheritable by default (:pep:`446`). Patch by Zackery Spytz and Victor
Stinner.
4 changes: 4 additions & 0 deletions Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2771,6 +2771,10 @@ _Py_get_osfhandle(int fd)
int
_Py_open_osfhandle_noraise(void *handle, int flags)
{
// PEP 446: Create non inheritable file descriptor by default,
// always set the _O_NOINHERIT flag.
flags |= _O_NOINHERIT;

int fd;
_Py_BEGIN_SUPPRESS_IPH
fd = _open_osfhandle((intptr_t)handle, flags);
Expand Down