18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#ifndef __PIDFD_H
48c2ecf20Sopenharmony_ci#define __PIDFD_H
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#define _GNU_SOURCE
78c2ecf20Sopenharmony_ci#include <errno.h>
88c2ecf20Sopenharmony_ci#include <fcntl.h>
98c2ecf20Sopenharmony_ci#include <sched.h>
108c2ecf20Sopenharmony_ci#include <signal.h>
118c2ecf20Sopenharmony_ci#include <stdio.h>
128c2ecf20Sopenharmony_ci#include <stdlib.h>
138c2ecf20Sopenharmony_ci#include <string.h>
148c2ecf20Sopenharmony_ci#include <syscall.h>
158c2ecf20Sopenharmony_ci#include <sys/mount.h>
168c2ecf20Sopenharmony_ci#include <sys/types.h>
178c2ecf20Sopenharmony_ci#include <sys/wait.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#include "../kselftest.h"
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#ifndef P_PIDFD
228c2ecf20Sopenharmony_ci#define P_PIDFD 3
238c2ecf20Sopenharmony_ci#endif
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#ifndef CLONE_NEWTIME
268c2ecf20Sopenharmony_ci#define CLONE_NEWTIME 0x00000080
278c2ecf20Sopenharmony_ci#endif
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#ifndef CLONE_PIDFD
308c2ecf20Sopenharmony_ci#define CLONE_PIDFD 0x00001000
318c2ecf20Sopenharmony_ci#endif
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#ifndef __NR_pidfd_open
348c2ecf20Sopenharmony_ci#define __NR_pidfd_open -1
358c2ecf20Sopenharmony_ci#endif
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#ifndef __NR_pidfd_send_signal
388c2ecf20Sopenharmony_ci#define __NR_pidfd_send_signal -1
398c2ecf20Sopenharmony_ci#endif
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#ifndef __NR_clone3
428c2ecf20Sopenharmony_ci#define __NR_clone3 -1
438c2ecf20Sopenharmony_ci#endif
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#ifndef __NR_pidfd_getfd
468c2ecf20Sopenharmony_ci#define __NR_pidfd_getfd -1
478c2ecf20Sopenharmony_ci#endif
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci#ifndef PIDFD_NONBLOCK
508c2ecf20Sopenharmony_ci#define PIDFD_NONBLOCK O_NONBLOCK
518c2ecf20Sopenharmony_ci#endif
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/*
548c2ecf20Sopenharmony_ci * The kernel reserves 300 pids via RESERVED_PIDS in kernel/pid.c
558c2ecf20Sopenharmony_ci * That means, when it wraps around any pid < 300 will be skipped.
568c2ecf20Sopenharmony_ci * So we need to use a pid > 300 in order to test recycling.
578c2ecf20Sopenharmony_ci */
588c2ecf20Sopenharmony_ci#define PID_RECYCLE 1000
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci/*
618c2ecf20Sopenharmony_ci * Define a few custom error codes for the child process to clearly indicate
628c2ecf20Sopenharmony_ci * what is happening. This way we can tell the difference between a system
638c2ecf20Sopenharmony_ci * error, a test error, etc.
648c2ecf20Sopenharmony_ci */
658c2ecf20Sopenharmony_ci#define PIDFD_PASS 0
668c2ecf20Sopenharmony_ci#define PIDFD_FAIL 1
678c2ecf20Sopenharmony_ci#define PIDFD_ERROR 2
688c2ecf20Sopenharmony_ci#define PIDFD_SKIP 3
698c2ecf20Sopenharmony_ci#define PIDFD_XFAIL 4
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic inline int wait_for_pid(pid_t pid)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	int status, ret;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ciagain:
768c2ecf20Sopenharmony_ci	ret = waitpid(pid, &status, 0);
778c2ecf20Sopenharmony_ci	if (ret == -1) {
788c2ecf20Sopenharmony_ci		if (errno == EINTR)
798c2ecf20Sopenharmony_ci			goto again;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci		ksft_print_msg("waitpid returned -1, errno=%d\n", errno);
828c2ecf20Sopenharmony_ci		return -1;
838c2ecf20Sopenharmony_ci	}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	if (!WIFEXITED(status)) {
868c2ecf20Sopenharmony_ci		ksft_print_msg(
878c2ecf20Sopenharmony_ci		       "waitpid !WIFEXITED, WIFSIGNALED=%d, WTERMSIG=%d\n",
888c2ecf20Sopenharmony_ci		       WIFSIGNALED(status), WTERMSIG(status));
898c2ecf20Sopenharmony_ci		return -1;
908c2ecf20Sopenharmony_ci	}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	ret = WEXITSTATUS(status);
938c2ecf20Sopenharmony_ci	ksft_print_msg("waitpid WEXITSTATUS=%d\n", ret);
948c2ecf20Sopenharmony_ci	return ret;
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic inline int sys_pidfd_open(pid_t pid, unsigned int flags)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	return syscall(__NR_pidfd_open, pid, flags);
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
1038c2ecf20Sopenharmony_ci					unsigned int flags)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cistatic inline int sys_pidfd_getfd(int pidfd, int fd, int flags)
1098c2ecf20Sopenharmony_ci{
1108c2ecf20Sopenharmony_ci	return syscall(__NR_pidfd_getfd, pidfd, fd, flags);
1118c2ecf20Sopenharmony_ci}
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_cistatic inline int sys_memfd_create(const char *name, unsigned int flags)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	return syscall(__NR_memfd_create, name, flags);
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci#endif /* __PIDFD_H */
119