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_NEWTIME
26  #define CLONE_NEWTIME 0x00000080
27  #endif
28  
29  #ifndef CLONE_PIDFD
30  #define CLONE_PIDFD 0x00001000
31  #endif
32  
33  #ifndef __NR_pidfd_open
34  #define __NR_pidfd_open -1
35  #endif
36  
37  #ifndef __NR_pidfd_send_signal
38  #define __NR_pidfd_send_signal -1
39  #endif
40  
41  #ifndef __NR_clone3
42  #define __NR_clone3 -1
43  #endif
44  
45  #ifndef __NR_pidfd_getfd
46  #define __NR_pidfd_getfd -1
47  #endif
48  
49  #ifndef PIDFD_NONBLOCK
50  #define PIDFD_NONBLOCK O_NONBLOCK
51  #endif
52  
53  /*
54   * The kernel reserves 300 pids via RESERVED_PIDS in kernel/pid.c
55   * 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 1000
59  
60  /*
61   * Define a few custom error codes for the child process to clearly indicate
62   * what is happening. This way we can tell the difference between a system
63   * error, a test error, etc.
64   */
65  #define PIDFD_PASS 0
66  #define PIDFD_FAIL 1
67  #define PIDFD_ERROR 2
68  #define PIDFD_SKIP 3
69  #define PIDFD_XFAIL 4
70  
wait_for_pid(pid_t pid)71  static inline int wait_for_pid(pid_t pid)
72  {
73  	int status, ret;
74  
75  again:
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  	ksft_print_msg("waitpid WEXITSTATUS=%d\n", ret);
94  	return ret;
95  }
96  
sys_pidfd_open(pid_t pid,unsigned int flags)97  static inline int sys_pidfd_open(pid_t pid, unsigned int flags)
98  {
99  	return syscall(__NR_pidfd_open, pid, flags);
100  }
101  
sys_pidfd_send_signal(int pidfd,int sig,siginfo_t * info,unsigned int flags)102  static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
103  					unsigned int flags)
104  {
105  	return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
106  }
107  
sys_pidfd_getfd(int pidfd,int fd,int flags)108  static inline int sys_pidfd_getfd(int pidfd, int fd, int flags)
109  {
110  	return syscall(__NR_pidfd_getfd, pidfd, fd, flags);
111  }
112  
sys_memfd_create(const char * name,unsigned int flags)113  static inline int sys_memfd_create(const char *name, unsigned int flags)
114  {
115  	return syscall(__NR_memfd_create, name, flags);
116  }
117  
118  #endif /* __PIDFD_H */
119