1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 #ifndef __PIDFD_H 4 #define __PIDFD_H 5 6 #define _GNU_SOURCE 7 #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_PIDFD 22 #define P_PIDFD 3 23 #endif 24 25 #ifndef CLONE_PIDFD 26 #define CLONE_PIDFD 0x00001000 27 #endif 28 29 #ifndef __NR_pidfd_open 30 #define __NR_pidfd_open -1 31 #endif 32 33 #ifndef __NR_pidfd_send_signal 34 #define __NR_pidfd_send_signal -1 35 #endif 36 37 #ifndef __NR_clone3 38 #define __NR_clone3 -1 39 #endif 40 41 #ifndef __NR_pidfd_getfd 42 #define __NR_pidfd_getfd -1 43 #endif 44 45 /* 46 * The kernel reserves 300 pids via RESERVED_PIDS in kernel/pid.c 47 * That means, when it wraps around any pid < 300 will be skipped. 48 * So we need to use a pid > 300 in order to test recycling. 49 */ 50 #define PID_RECYCLE 1000 51 52 /* 53 * Define a few custom error codes for the child process to clearly indicate 54 * what is happening. This way we can tell the difference between a system 55 * error, a test error, etc. 56 */ 57 #define PIDFD_PASS 0 58 #define PIDFD_FAIL 1 59 #define PIDFD_ERROR 2 60 #define PIDFD_SKIP 3 61 #define PIDFD_XFAIL 4 62 63 int wait_for_pid(pid_t pid) 64 { 65 int status, ret; 66 67 again: 68 ret = waitpid(pid, &status, 0); 69 if (ret == -1) { 70 if (errno == EINTR) 71 goto again; 72 73 return -1; 74 } 75 76 if (!WIFEXITED(status)) 77 return -1; 78 79 return WEXITSTATUS(status); 80 } 81 82 static inline int sys_pidfd_open(pid_t pid, unsigned int flags) 83 { 84 return syscall(__NR_pidfd_open, pid, flags); 85 } 86 87 static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info, 88 unsigned int flags) 89 { 90 return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags); 91 } 92 93 static inline int sys_pidfd_getfd(int pidfd, int fd, int flags) 94 { 95 return syscall(__NR_pidfd_getfd, pidfd, fd, flags); 96 } 97 98 static inline int sys_memfd_create(const char *name, unsigned int flags) 99 { 100 return syscall(__NR_memfd_create, name, flags); 101 } 102 103 #endif /* __PIDFD_H */ 104