xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/epoll_ctl/epoll_ctl05.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) Linux Test Project, 2021
4  * Author: Xie Ziyao <[email protected]>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Verify that epoll_ctl() fails with ELOOP if fd refers to an epoll instance
11  * and this EPOLL_CTL_ADD operation would result in a circular loop of epoll
12  * instances monitoring one another.
13  */
14 
15 #include <poll.h>
16 #include <sys/epoll.h>
17 
18 #include "tst_test.h"
19 
20 #define MAX_DEPTH 5
21 
22 static int epfd, origin_epfd, new_epfd;
23 static int fd[2];
24 
25 static struct epoll_event events = {.events = EPOLLIN};
26 
setup(void)27 static void setup(void)
28 {
29 	int i;
30 
31 	SAFE_PIPE(fd);
32 
33 	for (i = 0, epfd = fd[0]; i < MAX_DEPTH; i++, epfd = new_epfd) {
34 		new_epfd = epoll_create(1);
35 		if (new_epfd == -1)
36 			tst_brk(TBROK | TERRNO, "fail to create epoll instance");
37 
38 		if (i == 0)
39 			origin_epfd = new_epfd;
40 
41 		events.data.fd = epfd;
42 		if (epoll_ctl(new_epfd, EPOLL_CTL_ADD, epfd, &events))
43 			tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
44 	}
45 
46 	events.data.fd = fd[0];
47 	if (epoll_ctl(origin_epfd, EPOLL_CTL_DEL, fd[0], &events))
48 		tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_DEL, ...)");
49 }
50 
cleanup(void)51 static void cleanup(void)
52 {
53 	if (fd[0])
54 		SAFE_CLOSE(fd[0]);
55 
56 	if (fd[1])
57 		SAFE_CLOSE(fd[1]);
58 }
59 
verify_epoll_ctl(void)60 static void verify_epoll_ctl(void)
61 {
62 	events.data.fd = epfd;
63 	TST_EXP_FAIL(epoll_ctl(origin_epfd, EPOLL_CTL_ADD, epfd, &events),
64 		     ELOOP, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
65 }
66 
67 static struct tst_test test = {
68 	.setup = setup,
69 	.cleanup = cleanup,
70 	.test_all = verify_epoll_ctl,
71 };
72