* Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
*/
#ifndef IOCTL_PIDFD_H
#define IOCTL_PIDFD_H
#include "tst_test.h"
#include "lapi/pidfd.h"
static inline int ioctl_pidfd_get_info_supported(void)
{
pid_t pid;
int pidfd, ret;
int supported = 0;
struct pidfd_info info;
if (tst_kvercmp(6, 13, 0) >= 0)
return 1;
memset(&info, 0, sizeof(struct pidfd_info));
pid = SAFE_FORK();
if (!pid)
exit(100);
pidfd = SAFE_PIDFD_OPEN(pid, 0);
ret = ioctl(pidfd, PIDFD_GET_INFO, &info);
SAFE_WAITPID(pid, NULL, 0);
if (ret != -1)
supported = 1;
SAFE_CLOSE(pidfd);
return supported;
}
static inline int ioctl_pidfd_info_exit_supported(void)
{
int ret;
pid_t pid;
int pidfd;
int supported = 0;
struct pidfd_info info;
if (tst_kvercmp(6, 15, 0) >= 0)
return 1;
memset(&info, 0, sizeof(struct pidfd_info));
info.mask = PIDFD_INFO_EXIT;
pid = SAFE_FORK();
if (!pid)
exit(100);
pidfd = SAFE_PIDFD_OPEN(pid, 0);
SAFE_WAITPID(pid, NULL, 0);
ret = ioctl(pidfd, PIDFD_GET_INFO, &info);
if (ret == -1) {
* - EINVAL: until v6.13 kernel
* - ESRCH: all kernels between v6.13 and v6.15
*/
if (errno != ENOTTY &&
errno != EINVAL &&
errno != ESRCH)
tst_brk(TBROK | TERRNO, "ioctl error");
} else {
if (info.mask & PIDFD_INFO_EXIT)
supported = 1;
}
SAFE_CLOSE(pidfd);
return supported;
}
#endif