0001
0002
0003 #define _GNU_SOURCE
0004 #include <errno.h>
0005 #include <linux/types.h>
0006 #include <poll.h>
0007 #include <signal.h>
0008 #include <stdbool.h>
0009 #include <stdio.h>
0010 #include <stdlib.h>
0011 #include <string.h>
0012 #include <syscall.h>
0013 #include <sys/wait.h>
0014 #include <unistd.h>
0015
0016 #include "pidfd.h"
0017 #include "../kselftest.h"
0018
0019 static bool timeout;
0020
0021 static void handle_alarm(int sig)
0022 {
0023 timeout = true;
0024 }
0025
0026 int main(int argc, char **argv)
0027 {
0028 struct pollfd fds;
0029 int iter, nevents;
0030 int nr_iterations = 10000;
0031
0032 fds.events = POLLIN;
0033
0034 if (argc > 2)
0035 ksft_exit_fail_msg("Unexpected command line argument\n");
0036
0037 if (argc == 2) {
0038 nr_iterations = atoi(argv[1]);
0039 if (nr_iterations <= 0)
0040 ksft_exit_fail_msg("invalid input parameter %s\n",
0041 argv[1]);
0042 }
0043
0044 ksft_print_msg("running pidfd poll test for %d iterations\n",
0045 nr_iterations);
0046
0047 for (iter = 0; iter < nr_iterations; iter++) {
0048 int pidfd;
0049 int child_pid = fork();
0050
0051 if (child_pid < 0) {
0052 if (errno == EAGAIN) {
0053 iter--;
0054 continue;
0055 }
0056 ksft_exit_fail_msg(
0057 "%s - failed to fork a child process\n",
0058 strerror(errno));
0059 }
0060
0061 if (child_pid == 0) {
0062
0063 sleep(60);
0064 exit(EXIT_SUCCESS);
0065 }
0066
0067
0068 pidfd = sys_pidfd_open(child_pid, 0);
0069 if (pidfd < 0)
0070 ksft_exit_fail_msg("%s - pidfd_open failed\n",
0071 strerror(errno));
0072
0073
0074 if (signal(SIGALRM, handle_alarm) == SIG_ERR)
0075 ksft_exit_fail_msg("%s - signal failed\n",
0076 strerror(errno));
0077 alarm(3);
0078
0079
0080 if (sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0))
0081 ksft_exit_fail_msg("%s - pidfd_send_signal failed\n",
0082 strerror(errno));
0083
0084
0085 fds.fd = pidfd;
0086 nevents = poll(&fds, 1, -1);
0087
0088
0089 if (nevents < 0)
0090 ksft_exit_fail_msg("%s - poll failed\n",
0091 strerror(errno));
0092
0093 if (nevents != 1)
0094 ksft_exit_fail_msg("unexpected poll result: %d\n",
0095 nevents);
0096
0097 if (!(fds.revents & POLLIN))
0098 ksft_exit_fail_msg(
0099 "unexpected event type received: 0x%x\n",
0100 fds.revents);
0101
0102 if (timeout)
0103 ksft_exit_fail_msg(
0104 "death notification wait timeout\n");
0105
0106 close(pidfd);
0107
0108 if (waitpid(child_pid, NULL, 0) < 0)
0109 ksft_exit_fail_msg("%s - waitpid failed\n",
0110 strerror(errno));
0111
0112 }
0113
0114 ksft_test_result_pass("pidfd poll test: pass\n");
0115 return ksft_exit_pass();
0116 }