118 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2 3#ifndef __PIDFD_H4#define __PIDFD_H5 6#define _GNU_SOURCE7#include <errno.h>8#include <fcntl.h>9#include <sched.h>10#include <signal.h>11#include <stdio.h>12#include <stdlib.h>13#include <string.h>14#include <syscall.h>15#include <sys/mount.h>16#include <sys/types.h>17#include <sys/wait.h>18 19#include "../kselftest.h"20 21#ifndef P_PIDFD22#define P_PIDFD 323#endif24 25#ifndef CLONE_NEWTIME26#define CLONE_NEWTIME 0x0000008027#endif28 29#ifndef CLONE_PIDFD30#define CLONE_PIDFD 0x0000100031#endif32 33#ifndef __NR_pidfd_open34#define __NR_pidfd_open -135#endif36 37#ifndef __NR_pidfd_send_signal38#define __NR_pidfd_send_signal -139#endif40 41#ifndef __NR_clone342#define __NR_clone3 -143#endif44 45#ifndef __NR_pidfd_getfd46#define __NR_pidfd_getfd -147#endif48 49#ifndef PIDFD_NONBLOCK50#define PIDFD_NONBLOCK O_NONBLOCK51#endif52 53/*54 * The kernel reserves 300 pids via RESERVED_PIDS in kernel/pid.c55 * That means, when it wraps around any pid < 300 will be skipped.56 * So we need to use a pid > 300 in order to test recycling.57 */58#define PID_RECYCLE 100059 60/*61 * Define a few custom error codes for the child process to clearly indicate62 * what is happening. This way we can tell the difference between a system63 * error, a test error, etc.64 */65#define PIDFD_PASS 066#define PIDFD_FAIL 167#define PIDFD_ERROR 268#define PIDFD_SKIP 369#define PIDFD_XFAIL 470 71static inline int wait_for_pid(pid_t pid)72{73 int status, ret;74 75again:76 ret = waitpid(pid, &status, 0);77 if (ret == -1) {78 if (errno == EINTR)79 goto again;80 81 ksft_print_msg("waitpid returned -1, errno=%d\n", errno);82 return -1;83 }84 85 if (!WIFEXITED(status)) {86 ksft_print_msg(87 "waitpid !WIFEXITED, WIFSIGNALED=%d, WTERMSIG=%d\n",88 WIFSIGNALED(status), WTERMSIG(status));89 return -1;90 }91 92 ret = WEXITSTATUS(status);93 return ret;94}95 96static inline int sys_pidfd_open(pid_t pid, unsigned int flags)97{98 return syscall(__NR_pidfd_open, pid, flags);99}100 101static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info,102 unsigned int flags)103{104 return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);105}106 107static inline int sys_pidfd_getfd(int pidfd, int fd, int flags)108{109 return syscall(__NR_pidfd_getfd, pidfd, fd, flags);110}111 112static inline int sys_memfd_create(const char *name, unsigned int flags)113{114 return syscall(__NR_memfd_create, name, flags);115}116 117#endif /* __PIDFD_H */118