1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> 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 19static int fds[2]; 20static int epfd; 21 22static 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 34static 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 70static struct tst_test test = { 71 .cleanup = cleanup, 72 .test_all = run, 73}; 74