From 6f868fe1ded4d4137412cc1aae61373e9b0c941a Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Wed, 11 Sep 2024 17:13:23 -0700 Subject: [PATCH] Fix polling of files on Windows --- libc/calls/poll-nt.c | 4 +++- test/libc/calls/poll_test.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/libc/calls/poll-nt.c b/libc/calls/poll-nt.c index 6b9c1d233..867cfd108 100644 --- a/libc/calls/poll-nt.c +++ b/libc/calls/poll-nt.c @@ -179,7 +179,7 @@ textwindows static int sys_poll_nt_impl(struct pollfd *fds, uint64_t nfds, // check input status of pipes / consoles without blocking // this ensures any socket fds won't starve them of events - // if a file handle is POLLOUT only, we just mark it ready + // we can't poll file handles, so we just mark those ready for (i = 0; i < pn; ++i) { fi = fileindices[i]; ev = fds[fi].events; @@ -215,6 +215,8 @@ textwindows static int sys_poll_nt_impl(struct pollfd *fds, uint64_t nfds, fds[fi].revents = fds[fi].events & (POLLRDNORM_ | POLLWRNORM_); break; } + } else { + fds[fi].revents = fds[fi].events & (POLLRDNORM_ | POLLWRNORM_); } rc += !!fds[fi].revents; } diff --git a/test/libc/calls/poll_test.c b/test/libc/calls/poll_test.c index 97f429b27..12cf78951 100644 --- a/test/libc/calls/poll_test.c +++ b/test/libc/calls/poll_test.c @@ -310,6 +310,39 @@ TEST(poll, pipein_pollout_blocks) { EXPECT_SYS(0, 0, close(pipefds[0])); } +TEST(poll, pipein_file_noblock) { + if (IsFreebsd() || IsOpenbsd()) + return; + int pipefds[2]; + EXPECT_SYS(0, 3, open("boop", O_CREAT | O_RDWR | O_TRUNC, 0644)); + EXPECT_SYS(0, 0, pipe(pipefds)); + struct pollfd fds[] = {{pipefds[0], POLLIN}, {3, POLLIN}}; + EXPECT_SYS(0, 1, poll(fds, 2, -1u)); + EXPECT_TRUE(!!(fds[1].revents & POLLIN)); + EXPECT_TRUE(!(fds[1].revents & POLLOUT)); + EXPECT_SYS(0, 0, close(pipefds[1])); + EXPECT_SYS(0, 0, close(pipefds[0])); + EXPECT_SYS(0, 0, close(3)); +} + +TEST(poll, pipein_file_noblock2) { + if (IsFreebsd() || IsOpenbsd()) + return; + int pipefds[2]; + EXPECT_SYS(0, 3, open("boop", O_CREAT | O_RDWR | O_TRUNC, 0644)); + EXPECT_SYS(0, 0, pipe(pipefds)); + EXPECT_SYS(0, 1, write(5, "x", 1)); + struct pollfd fds[] = {{pipefds[0], POLLIN}, {3, POLLIN | POLLOUT}}; + EXPECT_SYS(0, 2, poll(fds, 2, -1u)); + EXPECT_TRUE(!!(fds[0].revents & POLLIN)); + EXPECT_TRUE(!(fds[0].revents & POLLOUT)); + EXPECT_TRUE(!!(fds[1].revents & POLLIN)); + EXPECT_TRUE(!!(fds[1].revents & POLLOUT)); + EXPECT_SYS(0, 0, close(pipefds[1])); + EXPECT_SYS(0, 0, close(pipefds[0])); + EXPECT_SYS(0, 0, close(3)); +} + TEST(poll, pipeout_pollout) { int pipefds[2]; EXPECT_SYS(0, 0, pipe(pipefds));