From 237b761f9a61ad1a821320e68f5a71e7cda6b29e Mon Sep 17 00:00:00 2001 From: Nayana Bidari Date: Mon, 28 Sep 2020 16:37:44 -0700 Subject: Fix lingering of TCP socket in the initial state. When the socket is set with SO_LINGER and close()'d in the initial state, it should not linger and return immediately. PiperOrigin-RevId: 334263149 --- test/syscalls/linux/tcp_socket.cc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'test/syscalls/linux') diff --git a/test/syscalls/linux/tcp_socket.cc b/test/syscalls/linux/tcp_socket.cc index ab731db1d..e0981e28a 100644 --- a/test/syscalls/linux/tcp_socket.cc +++ b/test/syscalls/linux/tcp_socket.cc @@ -1643,6 +1643,36 @@ TEST_P(SimpleTcpSocketTest, GetSocketDetachFilter) { SyscallFailsWithErrno(ENOPROTOOPT)); } +TEST_P(SimpleTcpSocketTest, CloseNonConnectedLingerOption) { + FileDescriptor s = + ASSERT_NO_ERRNO_AND_VALUE(Socket(GetParam(), SOCK_STREAM, IPPROTO_TCP)); + + constexpr int kLingerTimeout = 10; // Seconds. + + // Set the SO_LINGER option. + struct linger sl = { + .l_onoff = 1, + .l_linger = kLingerTimeout, + }; + ASSERT_THAT(setsockopt(s.get(), SOL_SOCKET, SO_LINGER, &sl, sizeof(sl)), + SyscallSucceeds()); + + struct pollfd poll_fd = { + .fd = s.get(), + .events = POLLHUP, + }; + constexpr int kPollTimeoutMs = 0; + ASSERT_THAT(RetryEINTR(poll)(&poll_fd, 1, kPollTimeoutMs), + SyscallSucceedsWithValue(1)); + + auto const start_time = absl::Now(); + EXPECT_THAT(close(s.release()), SyscallSucceeds()); + auto const end_time = absl::Now(); + + // Close() should not linger and return immediately. + ASSERT_LT((end_time - start_time), absl::Seconds(kLingerTimeout)); +} + INSTANTIATE_TEST_SUITE_P(AllInetTests, SimpleTcpSocketTest, ::testing::Values(AF_INET, AF_INET6)); -- cgit v1.2.3