diff --git a/test/syscalls/linux/tcp_socket.cc b/test/syscalls/linux/tcp_socket.cc index 59549dddc..932f4d254 100644 --- a/test/syscalls/linux/tcp_socket.cc +++ b/test/syscalls/linux/tcp_socket.cc @@ -994,6 +994,55 @@ TEST_P(TcpSocketTest, PollAfterShutdown) { SyscallSucceedsWithValue(1)); } +TEST_P(SimpleTcpSocketTest, PollAroundAccept) { + const FileDescriptor listener = + ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP)); + sockaddr_storage addr = + ASSERT_NO_ERRNO_AND_VALUE(InetLoopbackAddr(GetParam())); + socklen_t addrlen = sizeof(addr); + + // Bind to some port. + ASSERT_THAT(bind(listener.get(), AsSockAddr(&addr), addrlen), + SyscallSucceeds()); + ASSERT_THAT(listen(listener.get(), SOMAXCONN), SyscallSucceeds()); + + // Get the address we're bound to. We need to do this because we're allowing + // the stack to pick a port for us. + ASSERT_THAT(getsockname(listener.get(), AsSockAddr(&addr), &addrlen), + SyscallSucceeds()); + switch (GetParam()) { + case AF_INET: + ASSERT_EQ(addrlen, sizeof(sockaddr_in)); + break; + case AF_INET6: + ASSERT_EQ(addrlen, sizeof(sockaddr_in6)); + break; + } + + // Before the listener socket receives a connection, it should not be eligible + // for reading. + struct pollfd poll_fd = {listener.get(), POLLIN, 0}; + EXPECT_THAT(RetryEINTR(poll)(&poll_fd, /* nfds */ 1, /* timeout */ 0), + SyscallSucceedsWithValue(0)); + + FileDescriptor connector = + ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP)); + ASSERT_THAT(RetryEINTR(connect)(connector.get(), AsSockAddr(&addr), addrlen), + SyscallSucceeds()); + + // Now that a connection is pending, the listener is ready for a read. + ASSERT_THAT( + RetryEINTR(poll)(&poll_fd, /* nfds */ 1, /* infinite timeout */ -1), + SyscallSucceedsWithValue(1)); + + // Accept the connection. This should make the listener no longer ready for a + // read. + const FileDescriptor accepted = + ASSERT_NO_ERRNO_AND_VALUE(Accept(listener.get(), nullptr, nullptr)); + EXPECT_THAT(RetryEINTR(poll)(&poll_fd, /* nfds*/ 1, /* timeout */ 0), + SyscallSucceedsWithValue(0)); +} + TEST_P(SimpleTcpSocketTest, NonBlockingConnectRetry) { const FileDescriptor listener = ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP));