[PATCH v6] linux: use PIDFD_GET_INFO ioctl for pidfd_getpid() if available
luca.boccassi@gmail.com
luca.boccassi@gmail.com
Mon Jan 26 19:34:15 GMT 2026
From: Luca Boccassi <luca.boccassi@gmail.com>
Linux v6.13 introduced a new ioctl to query info from a pidfd.
The advantage of this vs. parsing /proc/ is that it works even
when procfs is not mounted. It's also a single syscall, and doesn't
need manual string parsing. Use it when available.
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
---
v2: use sys/pidfd.h instead of installed kernel headers
v3: add __ASSUME_PIDFD_GET_INFO
use atomics for support cache var
v4: drop support cache var
v5: drop static helper given it's just the ioctl call now, simplifies the flow
v6: map ENOTTY to EBADF to avoid breaking documented behaviour
sysdeps/unix/sysv/linux/kernel-features.h | 8 +++++
sysdeps/unix/sysv/linux/pidfd_getpid.c | 44 ++++++++++++++++++-----
2 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 01c865e2d5..94bdbbb730 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -269,4 +269,12 @@
# define __ASSUME_MSEAL 0
#endif
+/* The PIDFD_GET_INFO ioctl was introduced across all architectures in Linux
+ 6.13. */
+#if __LINUX_KERNEL_VERSION >= 0x060D00
+# define __ASSUME_PIDFD_GET_INFO 1
+#else
+# define __ASSUME_PIDFD_GET_INFO 0
+#endif
+
#endif /* kernel-features.h */
diff --git a/sysdeps/unix/sysv/linux/pidfd_getpid.c b/sysdeps/unix/sysv/linux/pidfd_getpid.c
index 860829cf07..e0f1b7bf2b 100644
--- a/sysdeps/unix/sysv/linux/pidfd_getpid.c
+++ b/sysdeps/unix/sysv/linux/pidfd_getpid.c
@@ -23,8 +23,11 @@
#include <stdlib.h>
#include <string.h>
#include <sysdep.h>
+#include <sys/ioctl.h>
+#include <sys/pidfd.h>
#include <unistd.h>
+#if !__ASSUME_PIDFD_GET_INFO
#define FDINFO_TO_FILENAME_PREFIX "/proc/self/fdinfo/"
#define FDINFO_FILENAME_LEN \
@@ -91,15 +94,9 @@ parse_fdinfo (const char *l, void *arg)
return 1;
}
-pid_t
-pidfd_getpid (int fd)
+static pid_t
+getpid_fdinfo (int fd)
{
- if (__glibc_unlikely (fd < 0))
- {
- __set_errno (EBADF);
- return -1;
- }
-
char fdinfoname[FDINFO_FILENAME_LEN];
char *p = mempcpy (fdinfoname, FDINFO_TO_FILENAME_PREFIX,
@@ -126,3 +123,34 @@ pidfd_getpid (int fd)
return fdinfo.pid;
}
+#endif
+
+pid_t
+pidfd_getpid (int fd)
+{
+ struct pidfd_info info = { .mask = PIDFD_INFO_PID };
+
+ if (__glibc_unlikely (fd < 0))
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
+
+ /* New in kernel 6.13 */
+ if (ioctl (fd, PIDFD_GET_INFO, &info) < 0)
+ {
+#if __ASSUME_PIDFD_GET_INFO
+ /* The procfs implementation returns EBADF when called with a non-pidfd
+ fd, change the errno to keep it consistent across implementations. */
+ if (errno == ENOTTY)
+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF);
+#else
+ if (errno == ENOTTY || errno == EINVAL)
+ return getpid_fdinfo (fd);
+#endif
+
+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (errno);
+ }
+
+ return info.pid;
+}
--
2.47.3
More information about the Libc-alpha
mailing list