// SPDX-License-Identifier: GPL-2.0

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <asm/unistd.h>
#include <linux/time_types.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <pthread.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include "../../kselftest_harness.h"

#define EVENTFD_TEST_ITERATIONS 100000UL

struct error {
	int  code;
	char msg[512];
};

static int error_set(struct error *err, int code, const char *fmt, ...)
{
	va_list args;
	int r;

	if (code == 0 || !err || err->code != 0)
		return code;

	err->code = code;
	va_start(args, fmt);
	r = vsnprintf(err->msg, sizeof(err->msg), fmt, args);
	assert((size_t)r < sizeof(err->msg));
	va_end(args);

	return code;
}

static inline int sys_eventfd2(unsigned int count, int flags)
{
	return syscall(__NR_eventfd2, count, flags);
}

TEST(eventfd_check_flag_rdwr)
{
	int fd, flags;

	fd = sys_eventfd2(0, 0);
	ASSERT_GE(fd, 0);

	flags = fcntl(fd, F_GETFL);
	// since the kernel automatically added O_RDWR.
	EXPECT_EQ(flags, O_RDWR);

	close(fd);
}

TEST(eventfd_check_flag_cloexec)
{
	int fd, flags;

	fd = sys_eventfd2(0, EFD_CLOEXEC);
	ASSERT_GE(fd, 0);

	flags = fcntl(fd, F_GETFD);
	ASSERT_GT(flags, -1);
	EXPECT_EQ(flags, FD_CLOEXEC);

	close(fd);
}

TEST(eventfd_check_flag_nonblock)
{
	int fd, flags;

	fd = sys_eventfd2(0, EFD_NONBLOCK);
	ASSERT_GE(fd, 0);

	flags = fcntl(fd, F_GETFL);
	ASSERT_GT(flags, -1);
	EXPECT_EQ(flags & EFD_NONBLOCK, EFD_NONBLOCK);
	EXPECT_EQ(flags & O_RDWR, O_RDWR);

	close(fd);
}

TEST(eventfd_chek_flag_cloexec_and_nonblock)
{
	int fd, flags;

	fd = sys_eventfd2(0, EFD_CLOEXEC|EFD_NONBLOCK);
	ASSERT_GE(fd, 0);

	flags = fcntl(fd, F_GETFL);
	ASSERT_GT(flags, -1);
	EXPECT_EQ(flags & EFD_NONBLOCK, EFD_NONBLOCK);
	EXPECT_EQ(flags & O_RDWR, O_RDWR);

	flags = fcntl(fd, F_GETFD);
	ASSERT_GT(flags, -1);
	EXPECT_EQ(flags, FD_CLOEXEC);

	close(fd);
}

static inline void trim_newline(char *str)
{
	char *pos = strrchr(str, '\n');

	if (pos)
		*pos = '\0';
}

static int verify_fdinfo(int fd, struct error *err, const char *prefix,
		size_t prefix_len, const char *expect, ...)
{
	char buffer[512] = {0, };
	char path[512] = {0, };
	va_list args;
	FILE *f;
	char *line = NULL;
	size_t n = 0;
	int found = 0;
	int r;

	va_start(args, expect);
	r = vsnprintf(buffer, sizeof(buffer), expect, args);
	assert((size_t)r < sizeof(buffer));
	va_end(args);

	snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", fd);
	f = fopen(path, "re");
	if (!f)
		return error_set(err, -1, "fdinfo open failed for %d", fd);

	while (getline(&line, &n, f) != -1) {
		char *val;

		if (strncmp(line, prefix, prefix_len))
			continue;

		found = 1;

		val = line + prefix_len;
		r = strcmp(val, buffer);
		if (r != 0) {
			trim_newline(line);
			trim_newline(buffer);
			error_set(err, -1, "%s '%s' != '%s'",
				  prefix, val, buffer);
		}
		break;
	}

	free(line);
	fclose(f);

	if (found == 0)
		return error_set(err, -1, "%s not found for fd %d",
				 prefix, fd);

	return 0;
}

TEST(eventfd_check_flag_semaphore)
{
	struct error err = {0};
	int fd, ret;

	fd = sys_eventfd2(0, EFD_SEMAPHORE);
	ASSERT_GE(fd, 0);

	ret = fcntl(fd, F_GETFL);
	ASSERT_GT(ret, -1);
	EXPECT_EQ(ret & O_RDWR, O_RDWR);

	// The semaphore could only be obtained from fdinfo.
	ret = verify_fdinfo(fd, &err, "eventfd-semaphore: ", 19, "1\n");
	if (ret != 0)
		ksft_print_msg("eventfd-semaphore check failed, msg: %s\n",
				err.msg);
	EXPECT_EQ(ret, 0);

	close(fd);
}

/*
 * A write(2) fails with the error EINVAL if the size of the supplied buffer
 * is less than 8 bytes, or if an attempt is made to write the value
 * 0xffffffffffffffff.
 */
TEST(eventfd_check_write)
{
	uint64_t value = 1;
	ssize_t size;
	int fd;

	fd = sys_eventfd2(0, 0);
	ASSERT_GE(fd, 0);

	size = write(fd, &value, sizeof(int));
	EXPECT_EQ(size, -1);
	EXPECT_EQ(errno, EINVAL);

	size = write(fd, &value, sizeof(value));
	EXPECT_EQ(size, sizeof(value));

	value = (uint64_t)-1;
	size = write(fd, &value, sizeof(value));
	EXPECT_EQ(size, -1);
	EXPECT_EQ(errno, EINVAL);

	close(fd);
}

/*
 * A read(2) fails with the error EINVAL if the size of the supplied buffer is
 * less than 8 bytes.
 */
TEST(eventfd_check_read)
{
	uint64_t value;
	ssize_t size;
	int fd;

	fd = sys_eventfd2(1, 0);
	ASSERT_GE(fd, 0);

	size = read(fd, &value, sizeof(int));
	EXPECT_EQ(size, -1);
	EXPECT_EQ(errno, EINVAL);

	size = read(fd, &value, sizeof(value));
	EXPECT_EQ(size, sizeof(value));
	EXPECT_EQ(value, 1);

	close(fd);
}


/*
 * If EFD_SEMAPHORE was not specified and the eventfd counter has a nonzero
 * value, then a read(2) returns 8 bytes containing that value, and the
 * counter's value is reset to zero.
 * If the eventfd counter is zero at the time of the call to read(2), then the
 * call fails with the error EAGAIN if the file descriptor has been made nonblocking.
 */
TEST(eventfd_check_read_with_nonsemaphore)
{
	uint64_t value;
	ssize_t size;
	int fd;
	int i;

	fd = sys_eventfd2(0, EFD_NONBLOCK);
	ASSERT_GE(fd, 0);

	value = 1;
	for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) {
		size = write(fd, &value, sizeof(value));
		EXPECT_EQ(size, sizeof(value));
	}

	size = read(fd, &value, sizeof(value));
	EXPECT_EQ(size, sizeof(uint64_t));
	EXPECT_EQ(value, EVENTFD_TEST_ITERATIONS);

	size = read(fd, &value, sizeof(value));
	EXPECT_EQ(size, -1);
	EXPECT_EQ(errno, EAGAIN);

	close(fd);
}

/*
 * If EFD_SEMAPHORE was specified and the eventfd counter has a nonzero value,
 * then a read(2) returns 8 bytes containing the value 1, and the counter's
 * value is decremented by 1.
 * If the eventfd counter is zero at the time of the call to read(2), then the
 * call fails with the error EAGAIN if the file descriptor has been made nonblocking.
 */
TEST(eventfd_check_read_with_semaphore)
{
	uint64_t value;
	ssize_t size;
	int fd;
	int i;

	fd = sys_eventfd2(0, EFD_SEMAPHORE|EFD_NONBLOCK);
	ASSERT_GE(fd, 0);

	value = 1;
	for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) {
		size = write(fd, &value, sizeof(value));
		EXPECT_EQ(size, sizeof(value));
	}

	for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) {
		size = read(fd, &value, sizeof(value));
		EXPECT_EQ(size, sizeof(value));
		EXPECT_EQ(value, 1);
	}

	size = read(fd, &value, sizeof(value));
	EXPECT_EQ(size, -1);
	EXPECT_EQ(errno, EAGAIN);

	close(fd);
}

TEST_HARNESS_MAIN
