1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) Linux Test Project, 2021
4f08c3bdfSopenharmony_ci * Author: Xie Ziyao <ziyaoxie@outlook.com>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*\
8f08c3bdfSopenharmony_ci * [Description]
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci * Verify that the maximum number of nesting allowed inside epoll sets is 5,
11f08c3bdfSopenharmony_ci * otherwise epoll_ctl fails with EINVAL.
12f08c3bdfSopenharmony_ci */
13f08c3bdfSopenharmony_ci
14f08c3bdfSopenharmony_ci#include <poll.h>
15f08c3bdfSopenharmony_ci#include <sys/epoll.h>
16f08c3bdfSopenharmony_ci
17f08c3bdfSopenharmony_ci#include "tst_test.h"
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_ci#define MAX_DEPTH 5
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_cistatic int epfd, new_epfd;
22f08c3bdfSopenharmony_cistatic int fd[2];
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_cistatic struct epoll_event events = {.events = EPOLLIN};
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_cistatic void setup(void)
27f08c3bdfSopenharmony_ci{
28f08c3bdfSopenharmony_ci	int depth;
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci	SAFE_PIPE(fd);
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci	for (depth = 0, epfd = fd[0]; depth < MAX_DEPTH; depth++) {
33f08c3bdfSopenharmony_ci		new_epfd = epoll_create(1);
34f08c3bdfSopenharmony_ci		if (new_epfd == -1)
35f08c3bdfSopenharmony_ci			tst_brk(TBROK | TERRNO, "fail to create epoll instance");
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_ci		events.data.fd = epfd;
38f08c3bdfSopenharmony_ci		if (epoll_ctl(new_epfd, EPOLL_CTL_ADD, epfd, &events))
39f08c3bdfSopenharmony_ci			tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_ci		epfd = new_epfd;
42f08c3bdfSopenharmony_ci	}
43f08c3bdfSopenharmony_ci}
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_cistatic void cleanup(void)
46f08c3bdfSopenharmony_ci{
47f08c3bdfSopenharmony_ci	if (fd[0])
48f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd[0]);
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci	if (fd[1])
51f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd[1]);
52f08c3bdfSopenharmony_ci}
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_cistatic void verify_epoll_ctl(void)
55f08c3bdfSopenharmony_ci{
56f08c3bdfSopenharmony_ci	new_epfd = epoll_create(1);
57f08c3bdfSopenharmony_ci	if (new_epfd == -1)
58f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "fail to create epoll instance");
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci	events.data.fd = epfd;
61f08c3bdfSopenharmony_ci	TST_EXP_FAIL(epoll_ctl(new_epfd, EPOLL_CTL_ADD, epfd, &events), EINVAL,
62f08c3bdfSopenharmony_ci		     "epoll_ctl(..., EPOLL_CTL_ADD, ...) with number of nesting is 5");
63f08c3bdfSopenharmony_ci	SAFE_CLOSE(new_epfd);
64f08c3bdfSopenharmony_ci}
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_cistatic struct tst_test test = {
67f08c3bdfSopenharmony_ci	.setup = setup,
68f08c3bdfSopenharmony_ci	.cleanup = cleanup,
69f08c3bdfSopenharmony_ci	.test_all = verify_epoll_ctl,
70f08c3bdfSopenharmony_ci};
71