[LTP] [PATCH v3] Introduce ioctl_pidfd_get_info_supported() function

Cyril Hrubis chrubis@suse.cz
Wed Sep 24 10:34:43 CEST 2025


Hi!
> +static inline bool ioctl_pidfd_get_info_supported(void)
> +{
> +	pid_t pid;
> +	int pidfd, ret;
> +	int supported = 0;
> +	struct pidfd_info info;
> +
> +	if (tst_kvercmp(6, 12, 0) >= 0)
> +		return 1;
> +
> +	memset(&info, 0, sizeof(struct pidfd_info));
> +
> +	pid = SAFE_FORK();
> +	if (!pid)
> +		exit(100);
> +
> +	pidfd = SAFE_PIDFD_OPEN(pid, 0);
> +	SAFE_WAITPID(pid, NULL, 0);

Again, please do not waitpid before the PIDFD_GET_INFO ioctl(). If you
do that it has no chance of succeeding.

>From fs/pidfd.c:

...
        task = get_pid_task(pid, PIDTYPE_PID);
        if (!task) {
                /*
                 * If the task has already been reaped, only exit
                 * information is available
                 */
                if (!(mask & PIDFD_INFO_EXIT))
                        return -ESRCH;

                goto copy_out;
        }
...

We have to do the ioctl() first and the waitpid() second for this case.

And if we do so we don't have to check the errno at all, the call will
just succeed in case that it's supported.

> +	ret = ioctl(pidfd, PIDFD_GET_INFO, &info);
> +	SAFE_CLOSE(pidfd);
> +
> +	if (ret == -1) {
> +		/* - ENOTTY: kernel too old, ioctl(PIDFD_GET_INFO) not implemented */
> +		if (errno == ENOTTY)
> +			supported = 0;
> +
> +		/* - EINVAL: ioctl(PIDFD_GET_INFO) exists but args invalid
> +		 * - ESRCH: ioctl(PIDFD_GET_INFO) exists but task already exited
> +		 * supported in both cases, but info.mask not set
> +		 */
> +		else if (errno == EINVAL || errno == ESRCH)
> +			supported = 1;
> +		else
> +			tst_brk(TBROK | TERRNO, "unexpected ioctl(PIDFD_GET_INFO) error");
> +	} else {
> +		supported = 1;
> +	}
> +
> +	return supported;
> +}
> +
>  static inline int ioctl_pidfd_info_exit_supported(void)
>  {
>  	int ret;
> diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c
> index c379717b3..d20c6f074 100644
> --- a/testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c
> +++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c
> @@ -14,7 +14,7 @@
>  #include "tst_test.h"
>  #include "lapi/pidfd.h"
>  #include "lapi/sched.h"
> -#include "lapi/ioctl.h"
> +#include "ioctl_pidfd.h"
>  
>  struct pidfd_info_invalid {
>  	uint32_t dummy;
> @@ -48,8 +48,15 @@ static void run(void)
>  	SAFE_CLOSE(pidfd);
>  }
>  
> +static void setup(void)
> +{
> +	if (!ioctl_pidfd_get_info_supported())
> +		tst_brk(TCONF, "ioctl(PIDFD_GET_INFO) is not implemented");
> +}
> +
>  static struct tst_test test = {
>  	.test_all = run,
> +	.setup = setup,
>  	.forks_child = 1,
>  	.bufs = (struct tst_buffers []) {
>  		{&args, .size = sizeof(*args)},
> -- 
> 2.51.0
> 

-- 
Cyril Hrubis
chrubis@suse.cz


More information about the ltp mailing list