pidfd_wait.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #define _GNU_SOURCE
  3. #include <errno.h>
  4. #include <linux/sched.h>
  5. #include <linux/types.h>
  6. #include <signal.h>
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <sched.h>
  11. #include <string.h>
  12. #include <sys/resource.h>
  13. #include <sys/time.h>
  14. #include <sys/types.h>
  15. #include <sys/wait.h>
  16. #include <unistd.h>
  17. #include "pidfd.h"
  18. #include "kselftest_harness.h"
  19. #define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr)))
  20. /* Attempt to de-conflict with the selftests tree. */
  21. #ifndef SKIP
  22. #define SKIP(s, ...) XFAIL(s, ##__VA_ARGS__)
  23. #endif
  24. TEST(wait_simple)
  25. {
  26. int pidfd = -1;
  27. pid_t parent_tid = -1;
  28. struct __clone_args args = {
  29. .parent_tid = ptr_to_u64(&parent_tid),
  30. .pidfd = ptr_to_u64(&pidfd),
  31. .flags = CLONE_PIDFD | CLONE_PARENT_SETTID,
  32. .exit_signal = SIGCHLD,
  33. };
  34. pid_t pid;
  35. siginfo_t info = {
  36. .si_signo = 0,
  37. };
  38. pidfd = open("/proc/self", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
  39. ASSERT_GE(pidfd, 0);
  40. pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED);
  41. ASSERT_NE(pid, 0);
  42. EXPECT_EQ(close(pidfd), 0);
  43. pidfd = -1;
  44. pidfd = open("/dev/null", O_RDONLY | O_CLOEXEC);
  45. ASSERT_GE(pidfd, 0);
  46. pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED);
  47. ASSERT_NE(pid, 0);
  48. EXPECT_EQ(close(pidfd), 0);
  49. pidfd = -1;
  50. pid = sys_clone3(&args, sizeof(args));
  51. ASSERT_GE(pid, 0);
  52. if (pid == 0)
  53. exit(EXIT_SUCCESS);
  54. pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED);
  55. ASSERT_GE(pid, 0);
  56. ASSERT_EQ(WIFEXITED(info.si_status), true);
  57. ASSERT_EQ(WEXITSTATUS(info.si_status), 0);
  58. EXPECT_EQ(close(pidfd), 0);
  59. ASSERT_EQ(info.si_signo, SIGCHLD);
  60. ASSERT_EQ(info.si_code, CLD_EXITED);
  61. ASSERT_EQ(info.si_pid, parent_tid);
  62. }
  63. TEST(wait_states)
  64. {
  65. int pidfd = -1;
  66. pid_t parent_tid = -1;
  67. struct __clone_args args = {
  68. .parent_tid = ptr_to_u64(&parent_tid),
  69. .pidfd = ptr_to_u64(&pidfd),
  70. .flags = CLONE_PIDFD | CLONE_PARENT_SETTID,
  71. .exit_signal = SIGCHLD,
  72. };
  73. int pfd[2];
  74. pid_t pid;
  75. siginfo_t info = {
  76. .si_signo = 0,
  77. };
  78. ASSERT_EQ(pipe(pfd), 0);
  79. pid = sys_clone3(&args, sizeof(args));
  80. ASSERT_GE(pid, 0);
  81. if (pid == 0) {
  82. char buf[2];
  83. close(pfd[1]);
  84. kill(getpid(), SIGSTOP);
  85. ASSERT_EQ(read(pfd[0], buf, 1), 1);
  86. close(pfd[0]);
  87. kill(getpid(), SIGSTOP);
  88. exit(EXIT_SUCCESS);
  89. }
  90. close(pfd[0]);
  91. ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WSTOPPED), 0);
  92. ASSERT_EQ(info.si_signo, SIGCHLD);
  93. ASSERT_EQ(info.si_code, CLD_STOPPED);
  94. ASSERT_EQ(info.si_pid, parent_tid);
  95. ASSERT_EQ(sys_pidfd_send_signal(pidfd, SIGCONT, NULL, 0), 0);
  96. ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WCONTINUED), 0);
  97. ASSERT_EQ(write(pfd[1], "C", 1), 1);
  98. close(pfd[1]);
  99. ASSERT_EQ(info.si_signo, SIGCHLD);
  100. ASSERT_EQ(info.si_code, CLD_CONTINUED);
  101. ASSERT_EQ(info.si_pid, parent_tid);
  102. ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WUNTRACED), 0);
  103. ASSERT_EQ(info.si_signo, SIGCHLD);
  104. ASSERT_EQ(info.si_code, CLD_STOPPED);
  105. ASSERT_EQ(info.si_pid, parent_tid);
  106. ASSERT_EQ(sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0), 0);
  107. ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WEXITED), 0);
  108. ASSERT_EQ(info.si_signo, SIGCHLD);
  109. ASSERT_EQ(info.si_code, CLD_KILLED);
  110. ASSERT_EQ(info.si_pid, parent_tid);
  111. EXPECT_EQ(close(pidfd), 0);
  112. }
  113. TEST(wait_nonblock)
  114. {
  115. int pidfd;
  116. unsigned int flags = 0;
  117. pid_t parent_tid = -1;
  118. struct __clone_args args = {
  119. .parent_tid = ptr_to_u64(&parent_tid),
  120. .flags = CLONE_PARENT_SETTID,
  121. .exit_signal = SIGCHLD,
  122. };
  123. int ret;
  124. pid_t pid;
  125. siginfo_t info = {
  126. .si_signo = 0,
  127. };
  128. /*
  129. * Callers need to see ECHILD with non-blocking pidfds when no child
  130. * processes exists.
  131. */
  132. pidfd = sys_pidfd_open(getpid(), PIDFD_NONBLOCK);
  133. EXPECT_GE(pidfd, 0) {
  134. /* pidfd_open() doesn't support PIDFD_NONBLOCK. */
  135. ASSERT_EQ(errno, EINVAL);
  136. SKIP(return, "Skipping PIDFD_NONBLOCK test");
  137. }
  138. ret = sys_waitid(P_PIDFD, pidfd, &info, WEXITED);
  139. ASSERT_LT(ret, 0);
  140. ASSERT_EQ(errno, ECHILD);
  141. EXPECT_EQ(close(pidfd), 0);
  142. pid = sys_clone3(&args, sizeof(args));
  143. ASSERT_GE(pid, 0);
  144. if (pid == 0) {
  145. kill(getpid(), SIGSTOP);
  146. exit(EXIT_SUCCESS);
  147. }
  148. pidfd = sys_pidfd_open(pid, PIDFD_NONBLOCK);
  149. EXPECT_GE(pidfd, 0) {
  150. /* pidfd_open() doesn't support PIDFD_NONBLOCK. */
  151. ASSERT_EQ(errno, EINVAL);
  152. SKIP(return, "Skipping PIDFD_NONBLOCK test");
  153. }
  154. flags = fcntl(pidfd, F_GETFL, 0);
  155. ASSERT_GT(flags, 0);
  156. ASSERT_GT((flags & O_NONBLOCK), 0);
  157. /*
  158. * Callers need to see EAGAIN/EWOULDBLOCK with non-blocking pidfd when
  159. * child processes exist but none have exited.
  160. */
  161. ret = sys_waitid(P_PIDFD, pidfd, &info, WEXITED);
  162. ASSERT_LT(ret, 0);
  163. ASSERT_EQ(errno, EAGAIN);
  164. /*
  165. * Callers need to continue seeing 0 with non-blocking pidfd and
  166. * WNOHANG raised explicitly when child processes exist but none have
  167. * exited.
  168. */
  169. ret = sys_waitid(P_PIDFD, pidfd, &info, WEXITED | WNOHANG);
  170. ASSERT_EQ(ret, 0);
  171. ASSERT_EQ(fcntl(pidfd, F_SETFL, (flags & ~O_NONBLOCK)), 0);
  172. ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WSTOPPED), 0);
  173. ASSERT_EQ(info.si_signo, SIGCHLD);
  174. ASSERT_EQ(info.si_code, CLD_STOPPED);
  175. ASSERT_EQ(info.si_pid, parent_tid);
  176. ASSERT_EQ(sys_pidfd_send_signal(pidfd, SIGCONT, NULL, 0), 0);
  177. ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WEXITED), 0);
  178. ASSERT_EQ(info.si_signo, SIGCHLD);
  179. ASSERT_EQ(info.si_code, CLD_EXITED);
  180. ASSERT_EQ(info.si_pid, parent_tid);
  181. EXPECT_EQ(close(pidfd), 0);
  182. }
  183. TEST_HARNESS_MAIN