[PATCH v3 6/9] syscalls: Add epoll_wait11
Cyril Hrubis <[email protected]>
| Newsgroups | gmane.linux.ltp |
|---|---|
| Message-ID | <[email protected]> |
A test that checks that EPOLLHUP is generated properly when a pipe is closed while epoll_wait() waits on the read end of a pipe. Signed-off-by: Cyril Hrubis <[email protected]> Reviewed-by: Andrea Cervesato <andrea.cervesato-IBi9RG/[email protected]> --- runtest/syscalls | 1 + .../kernel/syscalls/epoll_wait/.gitignore | 1 + .../kernel/syscalls/epoll_wait/epoll_wait11.c | 93 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait11.c diff --git a/runtest/syscalls b/runtest/syscalls index 08b31c9f5..269fc162a 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -199,6 +199,7 @@ epoll_wait07 epoll_wait07 epoll_wait08 epoll_wait08 epoll_wait09 epoll_wait09 epoll_wait10 epoll_wait10 +epoll_wait11 epoll_wait11 epoll_pwait01 epoll_pwait01 epoll_pwait02 epoll_pwait02 diff --git a/testcases/kernel/syscalls/epoll_wait/.gitignore b/testcases/kernel/syscalls/epoll_wait/.gitignore index 30139375d..57bdf0806 100644 --- a/testcases/kernel/syscalls/epoll_wait/.gitignore +++ b/testcases/kernel/syscalls/epoll_wait/.gitignore @@ -8,3 +8,4 @@ epoll_wait07 epoll_wait08 epoll_wait09 epoll_wait10 +epoll_wait11 diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait11.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait11.c new file mode 100644 index 000000000..12e158b22 --- /dev/null +++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait11.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 Cyril Hrubis <[email protected]> + */ + +/*\ + * Verify that :manpage:epoll_wait() reports EPOLLHUP when the write end of a + * pipe is closed while a child process is blocked in epoll_wait. + * + * [Algorithm] + * + * - Create a pipe and register the read end with an epoll instance for + * EPOLLIN. + * - Fork a child that blocks in epoll_wait on the pipe read end. + * - Parent waits for the child to enter sleep state, then closes the write + * end. + * - The child's :manpage:epoll_wait() should return with EPOLLHUP. + */ + +#include <sys/epoll.h> + +#include "tst_test.h" +#include "tst_epoll.h" + +static int efd = -1, fds[2] = {-1, -1}; + +static void run(void) +{ + pid_t pid; + + SAFE_PIPE(fds); + + efd = SAFE_EPOLL_CREATE1(0); + + struct epoll_event ev = { + .events = EPOLLIN, + .data.fd = fds[0], + }; + + SAFE_EPOLL_CTL(efd, EPOLL_CTL_ADD, fds[0], &ev); + + pid = SAFE_FORK(); + if (!pid) { + SAFE_CLOSE(fds[1]); + + TEST(epoll_wait(efd, &ev, 1, 5000)); + if (TST_RET != 1) { + tst_res(TFAIL | TTERRNO, + "epoll_wait() returned %li, expected 1", + TST_RET); + exit(0); + } + + if (ev.data.fd != fds[0]) { + tst_res(TFAIL, "epoll.data.fd %d, expected %d", + ev.data.fd, fds[0]); + exit(0); + } + + if (!(ev.events & EPOLLHUP)) { + tst_res(TFAIL, "events %x, EPOLLHUP not set", + ev.events); + exit(0); + } + + tst_res(TPASS, + "epoll_wait() reported EPOLLHUP on pipe hangup"); + exit(0); + } + + TST_PROCESS_STATE_WAIT(pid, 'S', 0); + SAFE_CLOSE(fds[1]); + SAFE_CLOSE(fds[0]); + SAFE_CLOSE(efd); +} + +static void cleanup(void) +{ + if (fds[1] != -1) + SAFE_CLOSE(fds[1]); + + if (fds[0] != -1) + SAFE_CLOSE(fds[0]); + + if (efd != -1) + SAFE_CLOSE(efd); +} + +static struct tst_test test = { + .test_all = run, + .cleanup = cleanup, + .forks_child = 1, +}; -- 2.53.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp