mirror of
https://github.com/python/cpython.git
synced 2026-01-26 21:03:34 +00:00
gh-139184: Set O_CLOEXEC for master_fd when calling os.forkpty() (#139408)
Signed-off-by: Manjusaka <me@manjusaka.me> Co-authored-by: Shamil <ashm.tech@proton.me> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
parent
f4104f5d74
commit
7cafd76a7f
@ -4592,6 +4592,8 @@ written in Python, such as a mail server's external command delivery program.
|
||||
master end of the pseudo-terminal. For a more portable approach, use the
|
||||
:mod:`pty` module. If an error occurs :exc:`OSError` is raised.
|
||||
|
||||
The returned file descriptor *fd* is :ref:`non-inheritable <fd_inheritance>`.
|
||||
|
||||
.. audit-event:: os.forkpty "" os.forkpty
|
||||
|
||||
.. warning::
|
||||
@ -4608,6 +4610,9 @@ written in Python, such as a mail server's external command delivery program.
|
||||
threads, this now raises a :exc:`DeprecationWarning`. See the
|
||||
longer explanation on :func:`os.fork`.
|
||||
|
||||
.. versionchanged:: next
|
||||
The returned file descriptor is now made non-inheritable.
|
||||
|
||||
.. availability:: Unix, not WASI, not Android, not iOS.
|
||||
|
||||
|
||||
|
||||
@ -33,9 +33,14 @@ The :mod:`pty` module defines the following functions:
|
||||
file descriptor connected to the child's controlling terminal (and also to the
|
||||
child's standard input and output).
|
||||
|
||||
The returned file descriptor *fd* is :ref:`non-inheritable <fd_inheritance>`.
|
||||
|
||||
.. warning:: On macOS the use of this function is unsafe when mixed with using
|
||||
higher-level system APIs, and that includes using :mod:`urllib.request`.
|
||||
|
||||
.. versionchanged:: next
|
||||
The returned file descriptor is now made non-inheritable.
|
||||
|
||||
|
||||
.. function:: openpty()
|
||||
|
||||
|
||||
@ -230,6 +230,7 @@ class PtyTest(unittest.TestCase):
|
||||
os._exit(2)
|
||||
os._exit(4)
|
||||
else:
|
||||
self.assertFalse(os.get_inheritable(master_fd))
|
||||
debug("Waiting for child (%d) to finish." % pid)
|
||||
# In verbose mode, we have to consume the debug output from the
|
||||
# child or the child will block, causing this test to hang in the
|
||||
|
||||
@ -0,0 +1 @@
|
||||
:func:`os.forkpty` does now make the returned file descriptor non-inheritable.
|
||||
5
Modules/clinic/posixmodule.c.h
generated
5
Modules/clinic/posixmodule.c.h
generated
@ -5035,7 +5035,8 @@ PyDoc_STRVAR(os_forkpty__doc__,
|
||||
"Returns a tuple of (pid, master_fd).\n"
|
||||
"Like fork(), return pid of 0 to the child process,\n"
|
||||
"and pid of child to the parent process.\n"
|
||||
"To both, return fd of newly opened pseudo-terminal.");
|
||||
"To both, return fd of newly opened pseudo-terminal.\n"
|
||||
"The master_fd is non-inheritable.");
|
||||
|
||||
#define OS_FORKPTY_METHODDEF \
|
||||
{"forkpty", (PyCFunction)os_forkpty, METH_NOARGS, os_forkpty__doc__},
|
||||
@ -13446,4 +13447,4 @@ exit:
|
||||
#ifndef OS__EMSCRIPTEN_LOG_METHODDEF
|
||||
#define OS__EMSCRIPTEN_LOG_METHODDEF
|
||||
#endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */
|
||||
/*[clinic end generated code: output=b5b370c499174f85 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=47ace1528820858b input=a9049054013a1b77]*/
|
||||
|
||||
@ -9018,11 +9018,12 @@ Returns a tuple of (pid, master_fd).
|
||||
Like fork(), return pid of 0 to the child process,
|
||||
and pid of child to the parent process.
|
||||
To both, return fd of newly opened pseudo-terminal.
|
||||
The master_fd is non-inheritable.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os_forkpty_impl(PyObject *module)
|
||||
/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
|
||||
/*[clinic end generated code: output=60d0a5c7512e4087 input=24765e0f33275b3b]*/
|
||||
{
|
||||
int master_fd = -1;
|
||||
pid_t pid;
|
||||
@ -9048,6 +9049,12 @@ os_forkpty_impl(PyObject *module)
|
||||
} else {
|
||||
/* parent: release the import lock. */
|
||||
PyOS_AfterFork_Parent();
|
||||
/* set O_CLOEXEC on master_fd */
|
||||
if (_Py_set_inheritable(master_fd, 0, NULL) < 0) {
|
||||
PyErr_FormatUnraisable("Exception ignored when setting master_fd "
|
||||
"non-inheritable in forkpty()");
|
||||
}
|
||||
|
||||
// After PyOS_AfterFork_Parent() starts the world to avoid deadlock.
|
||||
if (warn_about_fork_with_threads("forkpty") < 0)
|
||||
return NULL;
|
||||
@ -9055,6 +9062,7 @@ os_forkpty_impl(PyObject *module)
|
||||
if (pid == -1) {
|
||||
return posix_error();
|
||||
}
|
||||
|
||||
return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
|
||||
}
|
||||
#endif /* HAVE_FORKPTY */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user