1 /* SPDX-License-Identifier: GPL-2.0 */
5 #include <linux/sched.h>
6 #include <linux/types.h>
13 #include <sys/resource.h>
15 #include <sys/types.h>
20 #include "../kselftest_harness.h"
22 #define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr)))
24 /* Attempt to de-conflict with the selftests tree. */
26 #define SKIP(s, ...) XFAIL(s, ##__VA_ARGS__)
32 pid_t parent_tid
= -1;
33 struct __clone_args args
= {
34 .parent_tid
= ptr_to_u64(&parent_tid
),
35 .pidfd
= ptr_to_u64(&pidfd
),
36 .flags
= CLONE_PIDFD
| CLONE_PARENT_SETTID
,
37 .exit_signal
= SIGCHLD
,
44 pidfd
= open("/proc/self", O_DIRECTORY
| O_RDONLY
| O_CLOEXEC
);
47 pid
= sys_waitid(P_PIDFD
, pidfd
, &info
, WEXITED
);
49 EXPECT_EQ(close(pidfd
), 0);
52 pidfd
= open("/dev/null", O_RDONLY
| O_CLOEXEC
);
55 pid
= sys_waitid(P_PIDFD
, pidfd
, &info
, WEXITED
);
57 EXPECT_EQ(close(pidfd
), 0);
60 pid
= sys_clone3(&args
, sizeof(args
));
66 pid
= sys_waitid(P_PIDFD
, pidfd
, &info
, WEXITED
);
68 ASSERT_EQ(WIFEXITED(info
.si_status
), true);
69 ASSERT_EQ(WEXITSTATUS(info
.si_status
), 0);
70 EXPECT_EQ(close(pidfd
), 0);
72 ASSERT_EQ(info
.si_signo
, SIGCHLD
);
73 ASSERT_EQ(info
.si_code
, CLD_EXITED
);
74 ASSERT_EQ(info
.si_pid
, parent_tid
);
80 pid_t parent_tid
= -1;
81 struct __clone_args args
= {
82 .parent_tid
= ptr_to_u64(&parent_tid
),
83 .pidfd
= ptr_to_u64(&pidfd
),
84 .flags
= CLONE_PIDFD
| CLONE_PARENT_SETTID
,
85 .exit_signal
= SIGCHLD
,
93 ASSERT_EQ(pipe(pfd
), 0);
94 pid
= sys_clone3(&args
, sizeof(args
));
101 kill(getpid(), SIGSTOP
);
102 ASSERT_EQ(read(pfd
[0], buf
, 1), 1);
104 kill(getpid(), SIGSTOP
);
109 ASSERT_EQ(sys_waitid(P_PIDFD
, pidfd
, &info
, WSTOPPED
), 0);
110 ASSERT_EQ(info
.si_signo
, SIGCHLD
);
111 ASSERT_EQ(info
.si_code
, CLD_STOPPED
);
112 ASSERT_EQ(info
.si_pid
, parent_tid
);
114 ASSERT_EQ(sys_pidfd_send_signal(pidfd
, SIGCONT
, NULL
, 0), 0);
116 ASSERT_EQ(sys_waitid(P_PIDFD
, pidfd
, &info
, WCONTINUED
), 0);
117 ASSERT_EQ(write(pfd
[1], "C", 1), 1);
119 ASSERT_EQ(info
.si_signo
, SIGCHLD
);
120 ASSERT_EQ(info
.si_code
, CLD_CONTINUED
);
121 ASSERT_EQ(info
.si_pid
, parent_tid
);
123 ASSERT_EQ(sys_waitid(P_PIDFD
, pidfd
, &info
, WUNTRACED
), 0);
124 ASSERT_EQ(info
.si_signo
, SIGCHLD
);
125 ASSERT_EQ(info
.si_code
, CLD_STOPPED
);
126 ASSERT_EQ(info
.si_pid
, parent_tid
);
128 ASSERT_EQ(sys_pidfd_send_signal(pidfd
, SIGKILL
, NULL
, 0), 0);
130 ASSERT_EQ(sys_waitid(P_PIDFD
, pidfd
, &info
, WEXITED
), 0);
131 ASSERT_EQ(info
.si_signo
, SIGCHLD
);
132 ASSERT_EQ(info
.si_code
, CLD_KILLED
);
133 ASSERT_EQ(info
.si_pid
, parent_tid
);
135 EXPECT_EQ(close(pidfd
), 0);
141 unsigned int flags
= 0;
142 pid_t parent_tid
= -1;
143 struct __clone_args args
= {
144 .parent_tid
= ptr_to_u64(&parent_tid
),
145 .flags
= CLONE_PARENT_SETTID
,
146 .exit_signal
= SIGCHLD
,
155 * Callers need to see ECHILD with non-blocking pidfds when no child
158 pidfd
= sys_pidfd_open(getpid(), PIDFD_NONBLOCK
);
159 EXPECT_GE(pidfd
, 0) {
160 /* pidfd_open() doesn't support PIDFD_NONBLOCK. */
161 ASSERT_EQ(errno
, EINVAL
);
162 SKIP(return, "Skipping PIDFD_NONBLOCK test");
165 ret
= sys_waitid(P_PIDFD
, pidfd
, &info
, WEXITED
);
167 ASSERT_EQ(errno
, ECHILD
);
168 EXPECT_EQ(close(pidfd
), 0);
170 pid
= sys_clone3(&args
, sizeof(args
));
174 kill(getpid(), SIGSTOP
);
178 pidfd
= sys_pidfd_open(pid
, PIDFD_NONBLOCK
);
179 EXPECT_GE(pidfd
, 0) {
180 /* pidfd_open() doesn't support PIDFD_NONBLOCK. */
181 ASSERT_EQ(errno
, EINVAL
);
182 SKIP(return, "Skipping PIDFD_NONBLOCK test");
185 flags
= fcntl(pidfd
, F_GETFL
, 0);
187 ASSERT_GT((flags
& O_NONBLOCK
), 0);
190 * Callers need to see EAGAIN/EWOULDBLOCK with non-blocking pidfd when
191 * child processes exist but none have exited.
193 ret
= sys_waitid(P_PIDFD
, pidfd
, &info
, WEXITED
);
195 ASSERT_EQ(errno
, EAGAIN
);
198 * Callers need to continue seeing 0 with non-blocking pidfd and
199 * WNOHANG raised explicitly when child processes exist but none have
202 ret
= sys_waitid(P_PIDFD
, pidfd
, &info
, WEXITED
| WNOHANG
);
205 ASSERT_EQ(fcntl(pidfd
, F_SETFL
, (flags
& ~O_NONBLOCK
)), 0);
207 ASSERT_EQ(sys_waitid(P_PIDFD
, pidfd
, &info
, WSTOPPED
), 0);
208 ASSERT_EQ(info
.si_signo
, SIGCHLD
);
209 ASSERT_EQ(info
.si_code
, CLD_STOPPED
);
210 ASSERT_EQ(info
.si_pid
, parent_tid
);
212 ASSERT_EQ(sys_pidfd_send_signal(pidfd
, SIGCONT
, NULL
, 0), 0);
214 ASSERT_EQ(sys_waitid(P_PIDFD
, pidfd
, &info
, WEXITED
), 0);
215 ASSERT_EQ(info
.si_signo
, SIGCHLD
);
216 ASSERT_EQ(info
.si_code
, CLD_EXITED
);
217 ASSERT_EQ(info
.si_pid
, parent_tid
);
219 EXPECT_EQ(close(pidfd
), 0);