Skip to content

Commit 6c4c45e

Browse files
authored
bpo-38692: Add os.pidfd_open. (GH-17063)
1 parent 56698d5 commit 6c4c45e

File tree

6 files changed

+94
-1
lines changed

6 files changed

+94
-1
lines changed

Doc/library/os.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3539,6 +3539,19 @@ written in Python, such as a mail server's external command delivery program.
35393539
.. availability:: Unix.
35403540

35413541

3542+
.. function:: pidfd_open(pid, flags=0)
3543+
3544+
Return a file descriptor referring to the process *pid*. This descriptor can
3545+
be used to perform process management without races and signals. The *flags*
3546+
argument is provided for future extensions; no flag values are currently
3547+
defined.
3548+
3549+
See the :manpage:`pidfd_open(2)` man page for more details.
3550+
3551+
.. availability:: Linux 5.3+
3552+
.. versionadded:: 3.9
3553+
3554+
35423555
.. function:: plock(op)
35433556

35443557
Lock program segments into memory. The value of *op* (defined in

Doc/whatsnew/3.9.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ os
150150
Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for :attr:`si_code`.
151151
(Contributed by Dong-hee Na in :issue:`38493`.)
152152

153+
Exposed the Linux-specific :func:`os.pidfd_open` for process management with
154+
file descriptors. (:issue:`38692`)
155+
153156
threading
154157
---------
155158

Lib/test/test_posix.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,15 @@ def test_path_with_null_byte(self):
14701470
open(fn, 'wb').close()
14711471
self.assertRaises(ValueError, os.stat, fn_with_NUL)
14721472

1473+
@unittest.skipUnless(hasattr(os, "pidfd_open"), "pidfd_open unavailable")
1474+
def test_pidfd_open(self):
1475+
with self.assertRaises(OSError) as cm:
1476+
os.pidfd_open(-1)
1477+
if cm.exception.errno == errno.ENOSYS:
1478+
self.skipTest("system does not support pidfd_open")
1479+
self.assertEqual(cm.exception.errno, errno.EINVAL)
1480+
os.close(os.pidfd_open(os.getpid(), 0))
1481+
14731482
class PosixGroupsTester(unittest.TestCase):
14741483

14751484
def setUp(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Expose the Linux ``pidfd_open`` syscall as :func:`os.pidfd_open`.

Modules/clinic/posixmodule.c.h

Lines changed: 43 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/posixmodule.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7861,6 +7861,30 @@ os_wait_impl(PyObject *module)
78617861
}
78627862
#endif /* HAVE_WAIT */
78637863

7864+
#if defined(__linux__) && defined(__NR_pidfd_open)
7865+
/*[clinic input]
7866+
os.pidfd_open
7867+
pid: pid_t
7868+
flags: unsigned_int = 0
7869+
7870+
Return a file descriptor referring to the process *pid*.
7871+
7872+
The descriptor can be used to perform process management without races and
7873+
signals.
7874+
[clinic start generated code]*/
7875+
7876+
static PyObject *
7877+
os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
7878+
/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
7879+
{
7880+
int fd = syscall(__NR_pidfd_open, pid, flags);
7881+
if (fd < 0) {
7882+
return posix_error();
7883+
}
7884+
return PyLong_FromLong(fd);
7885+
}
7886+
#endif
7887+
78647888

78657889
#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
78667890
/*[clinic input]
@@ -13671,6 +13695,7 @@ static PyMethodDef posix_methods[] = {
1367113695
OS_WAIT4_METHODDEF
1367213696
OS_WAITID_METHODDEF
1367313697
OS_WAITPID_METHODDEF
13698+
OS_PIDFD_OPEN_METHODDEF
1367413699
OS_GETSID_METHODDEF
1367513700
OS_SETSID_METHODDEF
1367613701
OS_SETPGID_METHODDEF

0 commit comments

Comments
 (0)