[PATCH v6] linux: use PIDFD_GET_INFO ioctl for pidfd_getpid() if available

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Tue Jan 27 17:38:05 GMT 2026



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>

> ---
> 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;
> +}



More information about the Libc-alpha mailing list