1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2016 Fujitsu Ltd. 4f08c3bdfSopenharmony_ci * Author: Xiao Yang <yangx.jy@cn.fujitsu.com> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/*\ 8f08c3bdfSopenharmony_ci * [Description] 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * Check the basic functionality of the epoll_ctl: 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * - When epoll_ctl succeeds to register fd on the epoll instance and associates 13f08c3bdfSopenharmony_ci * event with fd, epoll_wait will get registered fd and event correctly. 14f08c3bdfSopenharmony_ci * - When epoll_ctl succeeds to change event which is related to fd, epoll_wait 15f08c3bdfSopenharmony_ci * will get changed event correctly. 16f08c3bdfSopenharmony_ci * - When epoll_ctl succeeds to deregister fd from the epoll instance epoll_wait 17f08c3bdfSopenharmony_ci * won't get deregistered fd and event. 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#include <poll.h> 21f08c3bdfSopenharmony_ci#include <sys/epoll.h> 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_ci#include "tst_test.h" 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_cistatic int epfd; 26f08c3bdfSopenharmony_cistatic int fd[2]; 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_cistatic struct epoll_event events[3] = { 29f08c3bdfSopenharmony_ci {.events = EPOLLIN}, 30f08c3bdfSopenharmony_ci {.events = EPOLLOUT}, 31f08c3bdfSopenharmony_ci {.events = EPOLLIN} 32f08c3bdfSopenharmony_ci}; 33f08c3bdfSopenharmony_ci 34f08c3bdfSopenharmony_cistatic void setup(void) 35f08c3bdfSopenharmony_ci{ 36f08c3bdfSopenharmony_ci epfd = epoll_create(2); 37f08c3bdfSopenharmony_ci if (epfd == -1) 38f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "fail to create epoll instance"); 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci SAFE_PIPE(fd); 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci events[0].data.fd = fd[0]; 43f08c3bdfSopenharmony_ci events[1].data.fd = fd[1]; 44f08c3bdfSopenharmony_ci events[2].data.fd = fd[1]; 45f08c3bdfSopenharmony_ci} 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_cistatic void cleanup(void) 48f08c3bdfSopenharmony_ci{ 49f08c3bdfSopenharmony_ci if (epfd > 0) 50f08c3bdfSopenharmony_ci SAFE_CLOSE(epfd); 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci if (fd[0] > 0) 53f08c3bdfSopenharmony_ci SAFE_CLOSE(fd[0]); 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_ci if (fd[1] > 0) 56f08c3bdfSopenharmony_ci SAFE_CLOSE(fd[1]); 57f08c3bdfSopenharmony_ci} 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_cistatic int has_event(struct epoll_event *epvs, int len, 60f08c3bdfSopenharmony_ci int fd, unsigned int events) 61f08c3bdfSopenharmony_ci{ 62f08c3bdfSopenharmony_ci int i; 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ci for (i = 0; i < len; i++) { 65f08c3bdfSopenharmony_ci if ((epvs[i].data.fd == fd) && (epvs[i].events == events)) 66f08c3bdfSopenharmony_ci return 1; 67f08c3bdfSopenharmony_ci } 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci return 0; 70f08c3bdfSopenharmony_ci} 71f08c3bdfSopenharmony_ci 72f08c3bdfSopenharmony_cistatic void check_epoll_ctl(int opt, int exp_num) 73f08c3bdfSopenharmony_ci{ 74f08c3bdfSopenharmony_ci int res; 75f08c3bdfSopenharmony_ci unsigned int events; 76f08c3bdfSopenharmony_ci char write_buf[] = "test"; 77f08c3bdfSopenharmony_ci char read_buf[sizeof(write_buf)]; 78f08c3bdfSopenharmony_ci struct epoll_event res_evs[2]; 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ci events = EPOLLIN; 81f08c3bdfSopenharmony_ci if (exp_num == 2) 82f08c3bdfSopenharmony_ci events |= EPOLLOUT; 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, fd[1], write_buf, sizeof(write_buf)); 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ci while (events) { 87f08c3bdfSopenharmony_ci int events_matched = 0; 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci memset(res_evs, 0, sizeof(res_evs)); 90f08c3bdfSopenharmony_ci res = epoll_wait(epfd, res_evs, 2, -1); 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci if (res <= 0) { 93f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "epoll_wait() returned %i", 94f08c3bdfSopenharmony_ci res); 95f08c3bdfSopenharmony_ci goto end; 96f08c3bdfSopenharmony_ci } 97f08c3bdfSopenharmony_ci 98f08c3bdfSopenharmony_ci if ((events & EPOLLIN) && 99f08c3bdfSopenharmony_ci has_event(res_evs, 2, fd[0], EPOLLIN)) { 100f08c3bdfSopenharmony_ci events_matched++; 101f08c3bdfSopenharmony_ci events &= ~EPOLLIN; 102f08c3bdfSopenharmony_ci } 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci if ((events & EPOLLOUT) && 105f08c3bdfSopenharmony_ci has_event(res_evs, 2, fd[1], EPOLLOUT)) { 106f08c3bdfSopenharmony_ci events_matched++; 107f08c3bdfSopenharmony_ci events &= ~EPOLLOUT; 108f08c3bdfSopenharmony_ci } 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci if (res != events_matched) { 111f08c3bdfSopenharmony_ci tst_res(TFAIL, 112f08c3bdfSopenharmony_ci "epoll_wait() returned unexpected events"); 113f08c3bdfSopenharmony_ci goto end; 114f08c3bdfSopenharmony_ci } 115f08c3bdfSopenharmony_ci } 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ci tst_res(TPASS, "epoll_ctl() succeeds with op %i", opt); 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ciend: 120f08c3bdfSopenharmony_ci SAFE_READ(1, fd[0], read_buf, sizeof(write_buf)); 121f08c3bdfSopenharmony_ci} 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_cistatic void opera_epoll_ctl(int opt, int fd, struct epoll_event *epvs) 124f08c3bdfSopenharmony_ci{ 125f08c3bdfSopenharmony_ci TEST(epoll_ctl(epfd, opt, fd, epvs)); 126f08c3bdfSopenharmony_ci if (TST_RET == -1) 127f08c3bdfSopenharmony_ci tst_brk(TBROK | TTERRNO, "epoll_ctl() fails with op %i", opt); 128f08c3bdfSopenharmony_ci} 129f08c3bdfSopenharmony_ci 130f08c3bdfSopenharmony_cistatic void verify_epoll_ctl(void) 131f08c3bdfSopenharmony_ci{ 132f08c3bdfSopenharmony_ci opera_epoll_ctl(EPOLL_CTL_ADD, fd[0], &events[0]); 133f08c3bdfSopenharmony_ci opera_epoll_ctl(EPOLL_CTL_ADD, fd[1], &events[2]); 134f08c3bdfSopenharmony_ci check_epoll_ctl(EPOLL_CTL_ADD, 1); 135f08c3bdfSopenharmony_ci opera_epoll_ctl(EPOLL_CTL_MOD, fd[1], &events[1]); 136f08c3bdfSopenharmony_ci check_epoll_ctl(EPOLL_CTL_MOD, 2); 137f08c3bdfSopenharmony_ci opera_epoll_ctl(EPOLL_CTL_DEL, fd[1], &events[1]); 138f08c3bdfSopenharmony_ci check_epoll_ctl(EPOLL_CTL_DEL, 1); 139f08c3bdfSopenharmony_ci opera_epoll_ctl(EPOLL_CTL_DEL, fd[0], &events[0]); 140f08c3bdfSopenharmony_ci} 141f08c3bdfSopenharmony_ci 142f08c3bdfSopenharmony_cistatic struct tst_test test = { 143f08c3bdfSopenharmony_ci .setup = setup, 144f08c3bdfSopenharmony_ci .cleanup = cleanup, 145f08c3bdfSopenharmony_ci .test_all = verify_epoll_ctl, 146f08c3bdfSopenharmony_ci}; 147