[PATCH v6] linux: use PIDFD_GET_INFO ioctl for pidfd_getpid() if available
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Tue Jan 27 17:45:46 GMT 2026
On 27/01/26 14:38, Adhemerval Zanella Netto wrote:
>
>
> On 26/01/26 16:34, luca.boccassi@gmail.com wrote:
>> 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>
>
> This version looks good to me, thanks.
>
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
I forgo to check the buildbot [1], and it shows a regression.
[1] https://www.delorie.com/trybots/32bit/57007/elf-check-localplt.out
>
>> ---
>> 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)
It needs to be __ioctl here to avoid the PLT call.
>> + {
>> +#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;
>> +}
>
More information about the Libc-alpha
mailing list