xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/epoll_wait/epoll_wait07.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2023 SUSE LLC Andrea Cervesato <[email protected]>
4  */
5 
6 /*\
7  * [Description]
8  *
9  * Verify that EPOLLONESHOT is correctly handled by epoll_wait.
10  * We open a channel, write in it two times and verify that EPOLLIN has been
11  * received only once.
12  */
13 
14 #include <poll.h>
15 #include <sys/epoll.h>
16 #include "tst_test.h"
17 #include "tst_epoll.h"
18 
19 static int fds[2];
20 static int epfd;
21 
cleanup(void)22 static void cleanup(void)
23 {
24 	if (epfd > 0)
25 		SAFE_CLOSE(epfd);
26 
27 	if (fds[0] > 0)
28 		SAFE_CLOSE(fds[0]);
29 
30 	if (fds[1] > 0)
31 		SAFE_CLOSE(fds[1]);
32 }
33 
run(void)34 static void run(void)
35 {
36 	struct epoll_event evt_receive;
37 	char buff = 'a';
38 
39 	SAFE_PIPE(fds);
40 
41 	tst_res(TINFO, "Polling on channel with EPOLLONESHOT");
42 
43 	epfd = SAFE_EPOLL_CREATE1(0);
44 
45 	SAFE_EPOLL_CTL(epfd, EPOLL_CTL_ADD, fds[0], &((struct epoll_event) {
46 		.events = EPOLLIN | EPOLLONESHOT,
47 		.data.fd = fds[0],
48 	}));
49 
50 	tst_res(TINFO, "Write channel for the 1st time. EPOLLIN expected");
51 
52 	SAFE_WRITE(0, fds[1], &buff, 1);
53 	TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 10, 0), 1);
54 	TST_EXP_EQ_LI(evt_receive.events & EPOLLIN, EPOLLIN);
55 	TST_EXP_EQ_LI(evt_receive.data.fd, fds[0]);
56 
57 	SAFE_READ(1, fds[0], &buff, 1);
58 	TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 10, 0), 0);
59 
60 	tst_res(TINFO, "Write channel for the 2nd time. No events expected");
61 
62 	SAFE_WRITE(0, fds[1], &buff, 1);
63 	TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 10, 0), 0);
64 
65 	SAFE_CLOSE(epfd);
66 	SAFE_CLOSE(fds[0]);
67 	SAFE_CLOSE(fds[1]);
68 }
69 
70 static struct tst_test test = {
71 	.cleanup = cleanup,
72 	.test_all = run,
73 };
74