Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#define _GNU_SOURCE
  4#include <errno.h>
  5#include <linux/types.h>
  6#include <poll.h>
  7#include <signal.h>
  8#include <stdbool.h>
  9#include <stdio.h>
 10#include <stdlib.h>
 11#include <string.h>
 12#include <syscall.h>
 13#include <sys/wait.h>
 14#include <unistd.h>
 15
 16#include "pidfd.h"
 17#include "../kselftest.h"
 18
 19static bool timeout;
 20
 21static void handle_alarm(int sig)
 22{
 23	timeout = true;
 24}
 25
 26int main(int argc, char **argv)
 27{
 28	struct pollfd fds;
 29	int iter, nevents;
 30	int nr_iterations = 10000;
 31
 32	fds.events = POLLIN;
 33
 34	if (argc > 2)
 35		ksft_exit_fail_msg("Unexpected command line argument\n");
 36
 37	if (argc == 2) {
 38		nr_iterations = atoi(argv[1]);
 39		if (nr_iterations <= 0)
 40			ksft_exit_fail_msg("invalid input parameter %s\n",
 41					argv[1]);
 42	}
 43
 44	ksft_print_msg("running pidfd poll test for %d iterations\n",
 45		nr_iterations);
 46
 47	for (iter = 0; iter < nr_iterations; iter++) {
 48		int pidfd;
 49		int child_pid = fork();
 50
 51		if (child_pid < 0) {
 52			if (errno == EAGAIN) {
 53				iter--;
 54				continue;
 55			}
 56			ksft_exit_fail_msg(
 57				"%s - failed to fork a child process\n",
 58				strerror(errno));
 59		}
 60
 61		if (child_pid == 0) {
 62			/* Child process just sleeps for a min and exits */
 63			sleep(60);
 64			exit(EXIT_SUCCESS);
 65		}
 66
 67		/* Parent kills the child and waits for its death */
 68		pidfd = sys_pidfd_open(child_pid, 0);
 69		if (pidfd < 0)
 70			ksft_exit_fail_msg("%s - pidfd_open failed\n",
 71					strerror(errno));
 72
 73		/* Setup 3 sec alarm - plenty of time */
 74		if (signal(SIGALRM, handle_alarm) == SIG_ERR)
 75			ksft_exit_fail_msg("%s - signal failed\n",
 76					strerror(errno));
 77		alarm(3);
 78
 79		/* Send SIGKILL to the child */
 80		if (sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0))
 81			ksft_exit_fail_msg("%s - pidfd_send_signal failed\n",
 82					strerror(errno));
 83
 84		/* Wait for the death notification */
 85		fds.fd = pidfd;
 86		nevents = poll(&fds, 1, -1);
 87
 88		/* Check for error conditions */
 89		if (nevents < 0)
 90			ksft_exit_fail_msg("%s - poll failed\n",
 91					strerror(errno));
 92
 93		if (nevents != 1)
 94			ksft_exit_fail_msg("unexpected poll result: %d\n",
 95					nevents);
 96
 97		if (!(fds.revents & POLLIN))
 98			ksft_exit_fail_msg(
 99				"unexpected event type received: 0x%x\n",
100				fds.revents);
101
102		if (timeout)
103			ksft_exit_fail_msg(
104				"death notification wait timeout\n");
105
106		close(pidfd);
107		/* Wait for child to prevent zombies */
108		if (waitpid(child_pid, NULL, 0) < 0)
109			ksft_exit_fail_msg("%s - waitpid failed\n",
110					strerror(errno));
111
112	}
113
114	ksft_test_result_pass("pidfd poll test: pass\n");
115	return ksft_exit_pass();
116}