[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