.. availability:: Unix.
+.. function:: pidfd_open(pid, flags=0)
+
+ Return a file descriptor referring to the process *pid*. This descriptor can
+ be used to perform process management without races and signals. The *flags*
+ argument is provided for future extensions; no flag values are currently
+ defined.
+
+ See the :manpage:`pidfd_open(2)` man page for more details.
+
+ .. availability:: Linux 5.3+
+ .. versionadded:: 3.9
+
+
.. function:: plock(op)
Lock program segments into memory. The value of *op* (defined in
open(fn, 'wb').close()
self.assertRaises(ValueError, os.stat, fn_with_NUL)
+ @unittest.skipUnless(hasattr(os, "pidfd_open"), "pidfd_open unavailable")
+ def test_pidfd_open(self):
+ with self.assertRaises(OSError) as cm:
+ os.pidfd_open(-1)
+ if cm.exception.errno == errno.ENOSYS:
+ self.skipTest("system does not support pidfd_open")
+ self.assertEqual(cm.exception.errno, errno.EINVAL)
+ os.close(os.pidfd_open(os.getpid(), 0))
+
class PosixGroupsTester(unittest.TestCase):
def setUp(self):
#endif /* defined(HAVE_WAIT) */
+#if (defined(__linux__) && defined(__NR_pidfd_open))
+
+PyDoc_STRVAR(os_pidfd_open__doc__,
+"pidfd_open($module, /, pid, flags=0)\n"
+"--\n"
+"\n"
+"Return a file descriptor referring to the process *pid*.\n"
+"\n"
+"The descriptor can be used to perform process management without races and\n"
+"signals.");
+
+#define OS_PIDFD_OPEN_METHODDEF \
+ {"pidfd_open", (PyCFunction)(void(*)(void))os_pidfd_open, METH_FASTCALL|METH_KEYWORDS, os_pidfd_open__doc__},
+
+static PyObject *
+os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags);
+
+static PyObject *
+os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"pid", "flags", NULL};
+ static _PyArg_Parser _parser = {"" _Py_PARSE_PID "|O&:pidfd_open", _keywords, 0};
+ pid_t pid;
+ unsigned int flags = 0;
+
+ if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+ &pid, _PyLong_UnsignedInt_Converter, &flags)) {
+ goto exit;
+ }
+ return_value = os_pidfd_open_impl(module, pid, flags);
+
+exit:
+ return return_value;
+}
+
+#endif /* (defined(__linux__) && defined(__NR_pidfd_open)) */
+
#if (defined(HAVE_READLINK) || defined(MS_WINDOWS))
PyDoc_STRVAR(os_readlink__doc__,
#define OS_WAIT_METHODDEF
#endif /* !defined(OS_WAIT_METHODDEF) */
+#ifndef OS_PIDFD_OPEN_METHODDEF
+ #define OS_PIDFD_OPEN_METHODDEF
+#endif /* !defined(OS_PIDFD_OPEN_METHODDEF) */
+
#ifndef OS_READLINK_METHODDEF
#define OS_READLINK_METHODDEF
#endif /* !defined(OS_READLINK_METHODDEF) */
#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF
#define OS__REMOVE_DLL_DIRECTORY_METHODDEF
#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */
-/*[clinic end generated code: output=c6e67d475eef00c4 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=51ba5b9536420cea input=a9049054013a1b77]*/
}
#endif /* HAVE_WAIT */
+#if defined(__linux__) && defined(__NR_pidfd_open)
+/*[clinic input]
+os.pidfd_open
+ pid: pid_t
+ flags: unsigned_int = 0
+
+Return a file descriptor referring to the process *pid*.
+
+The descriptor can be used to perform process management without races and
+signals.
+[clinic start generated code]*/
+
+static PyObject *
+os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
+/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
+{
+ int fd = syscall(__NR_pidfd_open, pid, flags);
+ if (fd < 0) {
+ return posix_error();
+ }
+ return PyLong_FromLong(fd);
+}
+#endif
+
#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
/*[clinic input]
OS_WAIT4_METHODDEF
OS_WAITID_METHODDEF
OS_WAITPID_METHODDEF
+ OS_PIDFD_OPEN_METHODDEF
OS_GETSID_METHODDEF
OS_SETSID_METHODDEF
OS_SETPGID_METHODDEF