tools/testing/selftests/pidfd/pidfd_wait.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/pidfd/pidfd_wait.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/pidfd/pidfd_wait.c
Extension
.c
Size
5305 bytes
Lines
223
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

#define _GNU_SOURCE
#include <errno.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "pidfd.h"
#include "kselftest_harness.h"

#define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr)))

/* Attempt to de-conflict with the selftests tree. */
#ifndef SKIP
#define SKIP(s, ...)	XFAIL(s, ##__VA_ARGS__)
#endif

TEST(wait_simple)
{
	int pidfd = -1;
	pid_t parent_tid = -1;
	struct __clone_args args = {
		.parent_tid = ptr_to_u64(&parent_tid),
		.pidfd = ptr_to_u64(&pidfd),
		.flags = CLONE_PIDFD | CLONE_PARENT_SETTID,
		.exit_signal = SIGCHLD,
	};
	pid_t pid;
	siginfo_t info = {
		.si_signo = 0,
	};

	pidfd = open("/proc/self", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
	ASSERT_GE(pidfd, 0);

	pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED);
	ASSERT_NE(pid, 0);
	EXPECT_EQ(close(pidfd), 0);
	pidfd = -1;

	pidfd = open("/dev/null", O_RDONLY | O_CLOEXEC);
	ASSERT_GE(pidfd, 0);

	pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED);
	ASSERT_NE(pid, 0);
	EXPECT_EQ(close(pidfd), 0);
	pidfd = -1;

	pid = sys_clone3(&args, sizeof(args));
	ASSERT_GE(pid, 0);

	if (pid == 0)
		exit(EXIT_SUCCESS);

	pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED);
	ASSERT_GE(pid, 0);
	ASSERT_EQ(WIFEXITED(info.si_status), true);
	ASSERT_EQ(WEXITSTATUS(info.si_status), 0);
	EXPECT_EQ(close(pidfd), 0);

	ASSERT_EQ(info.si_signo, SIGCHLD);
	ASSERT_EQ(info.si_code, CLD_EXITED);
	ASSERT_EQ(info.si_pid, parent_tid);
}

TEST(wait_states)
{
	int pidfd = -1;
	pid_t parent_tid = -1;
	struct __clone_args args = {
		.parent_tid = ptr_to_u64(&parent_tid),
		.pidfd = ptr_to_u64(&pidfd),
		.flags = CLONE_PIDFD | CLONE_PARENT_SETTID,
		.exit_signal = SIGCHLD,
	};
	int pfd[2];
	pid_t pid;
	siginfo_t info = {
		.si_signo = 0,
	};

Annotation

Implementation Notes