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 epoll_ctl() fails with ELOOP if fd refers to an epoll instance 11f08c3bdfSopenharmony_ci * and this EPOLL_CTL_ADD operation would result in a circular loop of epoll 12f08c3bdfSopenharmony_ci * instances monitoring one another. 13f08c3bdfSopenharmony_ci */ 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_ci#include <poll.h> 16f08c3bdfSopenharmony_ci#include <sys/epoll.h> 17f08c3bdfSopenharmony_ci 18f08c3bdfSopenharmony_ci#include "tst_test.h" 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#define MAX_DEPTH 5 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_cistatic int epfd, origin_epfd, new_epfd; 23f08c3bdfSopenharmony_cistatic int fd[2]; 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_cistatic struct epoll_event events = {.events = EPOLLIN}; 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_cistatic void setup(void) 28f08c3bdfSopenharmony_ci{ 29f08c3bdfSopenharmony_ci int i; 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci SAFE_PIPE(fd); 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci for (i = 0, epfd = fd[0]; i < MAX_DEPTH; i++, epfd = new_epfd) { 34f08c3bdfSopenharmony_ci new_epfd = epoll_create(1); 35f08c3bdfSopenharmony_ci if (new_epfd == -1) 36f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "fail to create epoll instance"); 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_ci if (i == 0) 39f08c3bdfSopenharmony_ci origin_epfd = new_epfd; 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_ci events.data.fd = epfd; 42f08c3bdfSopenharmony_ci if (epoll_ctl(new_epfd, EPOLL_CTL_ADD, epfd, &events)) 43f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)"); 44f08c3bdfSopenharmony_ci } 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci events.data.fd = fd[0]; 47f08c3bdfSopenharmony_ci if (epoll_ctl(origin_epfd, EPOLL_CTL_DEL, fd[0], &events)) 48f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_DEL, ...)"); 49f08c3bdfSopenharmony_ci} 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_cistatic void cleanup(void) 52f08c3bdfSopenharmony_ci{ 53f08c3bdfSopenharmony_ci if (fd[0]) 54f08c3bdfSopenharmony_ci SAFE_CLOSE(fd[0]); 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ci if (fd[1]) 57f08c3bdfSopenharmony_ci SAFE_CLOSE(fd[1]); 58f08c3bdfSopenharmony_ci} 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_cistatic void verify_epoll_ctl(void) 61f08c3bdfSopenharmony_ci{ 62f08c3bdfSopenharmony_ci events.data.fd = epfd; 63f08c3bdfSopenharmony_ci TST_EXP_FAIL(epoll_ctl(origin_epfd, EPOLL_CTL_ADD, epfd, &events), 64f08c3bdfSopenharmony_ci ELOOP, "epoll_ctl(..., EPOLL_CTL_ADD, ...)"); 65f08c3bdfSopenharmony_ci} 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_cistatic struct tst_test test = { 68f08c3bdfSopenharmony_ci .setup = setup, 69f08c3bdfSopenharmony_ci .cleanup = cleanup, 70f08c3bdfSopenharmony_ci .test_all = verify_epoll_ctl, 71f08c3bdfSopenharmony_ci}; 72