pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/1d75fa43a25e5f3c33f2aaaec28fab9430834792

b55097560d244c08.css" /> gh-77046: os.pipe() sets _O_NOINHERIT flag on fds (#113817) · python/cpython@1d75fa4 · GitHub
Skip to content

Commit 1d75fa4

Browse files
gh-77046: os.pipe() sets _O_NOINHERIT flag on fds (#113817)
On Windows, set _O_NOINHERIT flag on file descriptors created by os.pipe() and io.WindowsConsoleIO. Add test_pipe_spawnl() to test_os. Co-authored-by: Zackery Spytz <zspytz@gmail.com>
1 parent e82b096 commit 1d75fa4

File tree

5 files changed

+68
-6
lines changed

5 files changed

+68
-6
lines changed

Doc/library/msvcrt.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,14 @@ File Operations
7575
.. function:: open_osfhandle(handle, flags)
7676

7777
Create a C runtime file descriptor from the file handle *handle*. The *flags*
78-
parameter should be a bitwise OR of :const:`os.O_APPEND`, :const:`os.O_RDONLY`,
79-
and :const:`os.O_TEXT`. The returned file descriptor may be used as a parameter
78+
parameter should be a bitwise OR of :const:`os.O_APPEND`,
79+
:const:`os.O_RDONLY`, :const:`os.O_TEXT` and :const:`os.O_NOINHERIT`.
80+
The returned file descriptor may be used as a parameter
8081
to :func:`os.fdopen` to create a file object.
8182

83+
The file descriptor is inheritable by default. Pass :const:`os.O_NOINHERIT`
84+
flag to make it non inheritable.
85+
8286
.. audit-event:: msvcrt.open_osfhandle handle,flags msvcrt.open_osfhandle
8387

8488

Lib/test/test_os.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4485,6 +4485,61 @@ def test_openpty(self):
44854485
self.assertEqual(os.get_inheritable(master_fd), False)
44864486
self.assertEqual(os.get_inheritable(slave_fd), False)
44874487

4488+
@unittest.skipUnless(hasattr(os, 'spawnl'), "need os.openpty()")
4489+
def test_pipe_spawnl(self):
4490+
# gh-77046: On Windows, os.pipe() file descriptors must be created with
4491+
# _O_NOINHERIT to make them non-inheritable. UCRT has no public API to
4492+
# get (_osfile(fd) & _O_NOINHERIT), so use a functional test.
4493+
#
4494+
# Make sure that fd is not inherited by a child process created by
4495+
# os.spawnl(): get_osfhandle() and dup() must fail with EBADF.
4496+
4497+
fd, fd2 = os.pipe()
4498+
self.addCleanup(os.close, fd)
4499+
self.addCleanup(os.close, fd2)
4500+
4501+
code = textwrap.dedent(f"""
4502+
import errno
4503+
import os
4504+
import test.support
4505+
try:
4506+
import msvcrt
4507+
except ImportError:
4508+
msvcrt = None
4509+
4510+
fd = {fd}
4511+
4512+
with test.support.SuppressCrashReport():
4513+
if msvcrt is not None:
4514+
try:
4515+
handle = msvcrt.get_osfhandle(fd)
4516+
except OSError as exc:
4517+
if exc.errno != errno.EBADF:
4518+
raise
4519+
# get_osfhandle(fd) failed with EBADF as expected
4520+
else:
4521+
raise Exception("get_osfhandle() must fail")
4522+
4523+
try:
4524+
fd3 = os.dup(fd)
4525+
except OSError as exc:
4526+
if exc.errno != errno.EBADF:
4527+
raise
4528+
# os.dup(fd) failed with EBADF as expected
4529+
else:
4530+
os.close(fd3)
4531+
raise Exception("dup must fail")
4532+
""")
4533+
4534+
filename = os_helper.TESTFN
4535+
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
4536+
with open(filename, "w") as fp:
4537+
print(code, file=fp, end="")
4538+
4539+
cmd = [sys.executable, filename]
4540+
exitcode = os.spawnl(os.P_WAIT, cmd[0], *cmd)
4541+
self.assertEqual(exitcode, 0)
4542+
44884543

44894544
class PathTConverterTests(unittest.TestCase):
44904545
# tuples of (function name, allows fd arguments, additional arguments to
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
On Windows, file descriptors wrapping Windows handles are now created non
2+
inheritable by default (:pep:`446`). Patch by Zackery Spytz and Victor
3+
Stinner.

Modules/_io/winconsoleio.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,9 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
391391
}
392392

393393
if (self->writable)
394-
self->fd = _Py_open_osfhandle_noraise(handle, _O_WRONLY | _O_BINARY);
394+
self->fd = _Py_open_osfhandle_noraise(handle, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
395395
else
396-
self->fd = _Py_open_osfhandle_noraise(handle, _O_RDONLY | _O_BINARY);
396+
self->fd = _Py_open_osfhandle_noraise(handle, _O_RDONLY | _O_BINARY | _O_NOINHERIT);
397397
if (self->fd < 0) {
398398
PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
399399
CloseHandle(handle);

Modules/posixmodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11578,8 +11578,8 @@ os_pipe_impl(PyObject *module)
1157811578
Py_BEGIN_ALLOW_THREADS
1157911579
ok = CreatePipe(&read, &write, &attr, 0);
1158011580
if (ok) {
11581-
fds[0] = _Py_open_osfhandle_noraise(read, _O_RDONLY);
11582-
fds[1] = _Py_open_osfhandle_noraise(write, _O_WRONLY);
11581+
fds[0] = _Py_open_osfhandle_noraise(read, _O_RDONLY | _O_NOINHERIT);
11582+
fds[1] = _Py_open_osfhandle_noraise(write, _O_WRONLY | _O_NOINHERIT);
1158311583
if (fds[0] == -1 || fds[1] == -1) {
1158411584
CloseHandle(read);
1158511585
CloseHandle(write);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy