diff options
author | Ian Gudger <igudger@google.com> | 2019-03-21 13:18:00 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-03-21 13:19:11 -0700 |
commit | ba828233b9e934992ac024232e5018ce9971f334 (patch) | |
tree | 935ae24edc19af05f2ff3505beb60251c69666b6 /test/syscalls/linux/socket_generic.cc | |
parent | ba937d74f9a69893cde8c7e8cb9c2d1cdadb2b70 (diff) |
Clear msghdr flags on successful recvmsg.
.net sets these flags to -1 and then uses their result, especting it to be
zero.
Does not set actual flags (e.g. MSG_TRUNC), but setting to zero is more correct
than what we did before.
PiperOrigin-RevId: 239657951
Change-Id: I89c5f84bc9b94a2cd8ff84e8ecfea09e01142030
Diffstat (limited to 'test/syscalls/linux/socket_generic.cc')
-rw-r--r-- | test/syscalls/linux/socket_generic.cc | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/test/syscalls/linux/socket_generic.cc b/test/syscalls/linux/socket_generic.cc index 974c0dd7b..c83fb82fe 100644 --- a/test/syscalls/linux/socket_generic.cc +++ b/test/syscalls/linux/socket_generic.cc @@ -183,6 +183,80 @@ TEST_P(AllSocketPairTest, SendmsgRecvmsg16KB) { memcmp(sent_data.data(), received_data.data(), sent_data.size())); } +TEST_P(AllSocketPairTest, RecvmsgMsghdrFlagsNotClearedOnFailure) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + char received_data[10] = {}; + + struct iovec iov; + iov.iov_base = received_data; + iov.iov_len = sizeof(received_data); + struct msghdr msg = {}; + msg.msg_flags = -1; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); + + // Check that msghdr flags were not changed. + EXPECT_EQ(msg.msg_flags, -1); +} + +TEST_P(AllSocketPairTest, RecvmsgMsghdrFlagsCleared) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + char sent_data[10]; + RandomizeBuffer(sent_data, sizeof(sent_data)); + ASSERT_THAT( + RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0), + SyscallSucceedsWithValue(sizeof(sent_data))); + + char received_data[sizeof(sent_data)] = {}; + + struct iovec iov; + iov.iov_base = received_data; + iov.iov_len = sizeof(received_data); + struct msghdr msg = {}; + msg.msg_flags = -1; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0), + SyscallSucceedsWithValue(sizeof(sent_data))); + EXPECT_EQ(0, memcmp(received_data, sent_data, sizeof(sent_data))); + + // Check that msghdr flags were cleared. + EXPECT_EQ(msg.msg_flags, 0); +} + +TEST_P(AllSocketPairTest, RecvmsgPeekMsghdrFlagsCleared) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + char sent_data[10]; + RandomizeBuffer(sent_data, sizeof(sent_data)); + ASSERT_THAT( + RetryEINTR(send)(sockets->first_fd(), sent_data, sizeof(sent_data), 0), + SyscallSucceedsWithValue(sizeof(sent_data))); + + char received_data[sizeof(sent_data)] = {}; + + struct iovec iov; + iov.iov_base = received_data; + iov.iov_len = sizeof(received_data); + struct msghdr msg = {}; + msg.msg_flags = -1; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_PEEK), + SyscallSucceedsWithValue(sizeof(sent_data))); + EXPECT_EQ(0, memcmp(received_data, sent_data, sizeof(sent_data))); + + // Check that msghdr flags were cleared. + EXPECT_EQ(msg.msg_flags, 0); +} + TEST_P(AllSocketPairTest, RecvmmsgInvalidTimeout) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); char buf[10]; |