1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2016 Fujitsu Ltd.
4f08c3bdfSopenharmony_ci * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
5f08c3bdfSopenharmony_ci * Copyright (c) 2021 Xie Ziyao <xieziyao@huawei.com>
6f08c3bdfSopenharmony_ci */
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_ci/*\
9f08c3bdfSopenharmony_ci * [Description]
10f08c3bdfSopenharmony_ci *
11f08c3bdfSopenharmony_ci * Basic test for epoll_wait:
12f08c3bdfSopenharmony_ci *
13f08c3bdfSopenharmony_ci * - epoll_wait fails with EBADF if epfd is not a valid file descriptor.
14f08c3bdfSopenharmony_ci * - epoll_wait fails with EINVAL if epfd is not an epoll file descriptor.
15f08c3bdfSopenharmony_ci * - epoll_wait fails with EINVAL if maxevents is less than zero.
16f08c3bdfSopenharmony_ci * - epoll_wait fails with EINVAL if maxevents is equal to zero.
17f08c3bdfSopenharmony_ci * - epoll_wait fails with EFAULT if the memory area pointed to by events is
18f08c3bdfSopenharmony_ci *   not accessible with write permissions.
19f08c3bdfSopenharmony_ci */
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_ci#include <sys/mman.h>
22f08c3bdfSopenharmony_ci#include <sys/epoll.h>
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_ci#include "tst_test.h"
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_cistatic struct epoll_event epevs[1] = {
27f08c3bdfSopenharmony_ci	{.events = EPOLLOUT}
28f08c3bdfSopenharmony_ci};
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_cistatic struct epoll_event *ev_rdonly, *ev_rdwr = epevs;
31f08c3bdfSopenharmony_cistatic int fds[2], epfd, inv_epfd, bad_epfd = -1;
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_cistatic struct test_case_t {
34f08c3bdfSopenharmony_ci	int *epfd;
35f08c3bdfSopenharmony_ci	struct epoll_event **ev;
36f08c3bdfSopenharmony_ci	int maxevents;
37f08c3bdfSopenharmony_ci	int exp_errno;
38f08c3bdfSopenharmony_ci	const char *desc;
39f08c3bdfSopenharmony_ci} tc[] = {
40f08c3bdfSopenharmony_ci	{&bad_epfd, &ev_rdwr, 1, EBADF, "epfd is not a valid fd"},
41f08c3bdfSopenharmony_ci	{&inv_epfd, &ev_rdwr, 1, EINVAL, "epfd is not an epoll fd"},
42f08c3bdfSopenharmony_ci	{&epfd, &ev_rdwr, -1, EINVAL, "maxevents is less than zero"},
43f08c3bdfSopenharmony_ci	{&epfd, &ev_rdwr, 0, EINVAL, "maxevents is equal to zero"},
44f08c3bdfSopenharmony_ci	{&epfd, &ev_rdonly, 1, EFAULT, "events has no write permissions"}
45f08c3bdfSopenharmony_ci};
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_cistatic void setup(void)
48f08c3bdfSopenharmony_ci{
49f08c3bdfSopenharmony_ci	ev_rdonly = SAFE_MMAP(NULL, getpagesize(), PROT_READ,
50f08c3bdfSopenharmony_ci			      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
51f08c3bdfSopenharmony_ci	SAFE_PIPE(fds);
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci	epfd = epoll_create(1);
54f08c3bdfSopenharmony_ci	if (epfd == -1)
55f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "epoll_create()");
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_ci	epevs[0].data.fd = fds[1];
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_ci	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[0]))
60f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
61f08c3bdfSopenharmony_ci}
62f08c3bdfSopenharmony_ci
63f08c3bdfSopenharmony_cistatic void verify_epoll_wait(unsigned int n)
64f08c3bdfSopenharmony_ci{
65f08c3bdfSopenharmony_ci	TST_EXP_FAIL(epoll_wait(*tc[n].epfd, *tc[n].ev, tc[n].maxevents, -1),
66f08c3bdfSopenharmony_ci		     tc[n].exp_errno, "epoll_wait() %s", tc[n].desc);
67f08c3bdfSopenharmony_ci}
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_cistatic void cleanup(void)
70f08c3bdfSopenharmony_ci{
71f08c3bdfSopenharmony_ci	if (epfd > 0)
72f08c3bdfSopenharmony_ci		SAFE_CLOSE(epfd);
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	if (fds[0] > 0)
75f08c3bdfSopenharmony_ci		SAFE_CLOSE(fds[0]);
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ci	if (fds[1] > 0)
78f08c3bdfSopenharmony_ci		SAFE_CLOSE(fds[1]);
79f08c3bdfSopenharmony_ci}
80f08c3bdfSopenharmony_ci
81f08c3bdfSopenharmony_cistatic struct tst_test test = {
82f08c3bdfSopenharmony_ci	.setup = setup,
83f08c3bdfSopenharmony_ci	.cleanup = cleanup,
84f08c3bdfSopenharmony_ci	.test = verify_epoll_wait,
85f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(tc),
86f08c3bdfSopenharmony_ci};
87