[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.