gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/readv_socket.cc (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <errno.h> 16 #include <fcntl.h> 17 #include <sys/socket.h> 18 #include <sys/types.h> 19 #include <unistd.h> 20 21 #include "gtest/gtest.h" 22 #include "test/syscalls/linux/readv_common.h" 23 #include "test/util/test_util.h" 24 25 namespace gvisor { 26 namespace testing { 27 28 namespace { 29 30 class ReadvSocketTest : public ::testing::Test { 31 public: 32 void SetUp() override { 33 test_unix_stream_socket_[0] = -1; 34 test_unix_stream_socket_[1] = -1; 35 test_unix_dgram_socket_[0] = -1; 36 test_unix_dgram_socket_[1] = -1; 37 test_unix_seqpacket_socket_[0] = -1; 38 test_unix_seqpacket_socket_[1] = -1; 39 40 ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, test_unix_stream_socket_), 41 SyscallSucceeds()); 42 ASSERT_THAT(fcntl(test_unix_stream_socket_[0], F_SETFL, O_NONBLOCK), 43 SyscallSucceeds()); 44 ASSERT_THAT(socketpair(AF_UNIX, SOCK_DGRAM, 0, test_unix_dgram_socket_), 45 SyscallSucceeds()); 46 ASSERT_THAT(fcntl(test_unix_dgram_socket_[0], F_SETFL, O_NONBLOCK), 47 SyscallSucceeds()); 48 ASSERT_THAT( 49 socketpair(AF_UNIX, SOCK_SEQPACKET, 0, test_unix_seqpacket_socket_), 50 SyscallSucceeds()); 51 ASSERT_THAT(fcntl(test_unix_seqpacket_socket_[0], F_SETFL, O_NONBLOCK), 52 SyscallSucceeds()); 53 54 ASSERT_THAT( 55 write(test_unix_stream_socket_[1], kReadvTestData, kReadvTestDataSize), 56 SyscallSucceedsWithValue(kReadvTestDataSize)); 57 ASSERT_THAT( 58 write(test_unix_dgram_socket_[1], kReadvTestData, kReadvTestDataSize), 59 SyscallSucceedsWithValue(kReadvTestDataSize)); 60 ASSERT_THAT(write(test_unix_seqpacket_socket_[1], kReadvTestData, 61 kReadvTestDataSize), 62 SyscallSucceedsWithValue(kReadvTestDataSize)); 63 } 64 65 void TearDown() override { 66 close(test_unix_stream_socket_[0]); 67 close(test_unix_stream_socket_[1]); 68 69 close(test_unix_dgram_socket_[0]); 70 close(test_unix_dgram_socket_[1]); 71 72 close(test_unix_seqpacket_socket_[0]); 73 close(test_unix_seqpacket_socket_[1]); 74 } 75 76 int test_unix_stream_socket_[2]; 77 int test_unix_dgram_socket_[2]; 78 int test_unix_seqpacket_socket_[2]; 79 }; 80 81 TEST_F(ReadvSocketTest, ReadOneBufferPerByte_StreamSocket) { 82 ReadOneBufferPerByte(test_unix_stream_socket_[0]); 83 } 84 85 TEST_F(ReadvSocketTest, ReadOneBufferPerByte_DgramSocket) { 86 ReadOneBufferPerByte(test_unix_dgram_socket_[0]); 87 } 88 89 TEST_F(ReadvSocketTest, ReadOneBufferPerByte_SeqPacketSocket) { 90 ReadOneBufferPerByte(test_unix_seqpacket_socket_[0]); 91 } 92 93 TEST_F(ReadvSocketTest, ReadOneHalfAtATime_StreamSocket) { 94 ReadOneHalfAtATime(test_unix_stream_socket_[0]); 95 } 96 97 TEST_F(ReadvSocketTest, ReadOneHalfAtATime_DgramSocket) { 98 ReadOneHalfAtATime(test_unix_dgram_socket_[0]); 99 } 100 101 TEST_F(ReadvSocketTest, ReadAllOneBuffer_StreamSocket) { 102 ReadAllOneBuffer(test_unix_stream_socket_[0]); 103 } 104 105 TEST_F(ReadvSocketTest, ReadAllOneBuffer_DgramSocket) { 106 ReadAllOneBuffer(test_unix_dgram_socket_[0]); 107 } 108 109 TEST_F(ReadvSocketTest, ReadAllOneLargeBuffer_StreamSocket) { 110 ReadAllOneLargeBuffer(test_unix_stream_socket_[0]); 111 } 112 113 TEST_F(ReadvSocketTest, ReadAllOneLargeBuffer_DgramSocket) { 114 ReadAllOneLargeBuffer(test_unix_dgram_socket_[0]); 115 } 116 117 TEST_F(ReadvSocketTest, ReadBuffersOverlapping_StreamSocket) { 118 ReadBuffersOverlapping(test_unix_stream_socket_[0]); 119 } 120 121 TEST_F(ReadvSocketTest, ReadBuffersOverlapping_DgramSocket) { 122 ReadBuffersOverlapping(test_unix_dgram_socket_[0]); 123 } 124 125 TEST_F(ReadvSocketTest, ReadBuffersDiscontinuous_StreamSocket) { 126 ReadBuffersDiscontinuous(test_unix_stream_socket_[0]); 127 } 128 129 TEST_F(ReadvSocketTest, ReadBuffersDiscontinuous_DgramSocket) { 130 ReadBuffersDiscontinuous(test_unix_dgram_socket_[0]); 131 } 132 133 TEST_F(ReadvSocketTest, ReadIovecsCompletelyFilled_StreamSocket) { 134 ReadIovecsCompletelyFilled(test_unix_stream_socket_[0]); 135 } 136 137 TEST_F(ReadvSocketTest, ReadIovecsCompletelyFilled_DgramSocket) { 138 ReadIovecsCompletelyFilled(test_unix_dgram_socket_[0]); 139 } 140 141 TEST_F(ReadvSocketTest, BadIovecsPointer_StreamSocket) { 142 #pragma GCC diagnostic push 143 #pragma GCC diagnostic ignored "-Wnonnull" 144 ASSERT_THAT(readv(test_unix_stream_socket_[0], nullptr, 1), 145 SyscallFailsWithErrno(EFAULT)); 146 #pragma GCC diagnostic pop 147 } 148 149 TEST_F(ReadvSocketTest, BadIovecsPointer_DgramSocket) { 150 #pragma GCC diagnostic push 151 #pragma GCC diagnostic ignored "-Wnonnull" 152 ASSERT_THAT(readv(test_unix_dgram_socket_[0], nullptr, 1), 153 SyscallFailsWithErrno(EFAULT)); 154 #pragma GCC diagnostic pop 155 } 156 157 TEST_F(ReadvSocketTest, BadIovecBase_StreamSocket) { 158 struct iovec iov[1]; 159 iov[0].iov_base = nullptr; 160 iov[0].iov_len = 1024; 161 ASSERT_THAT(readv(test_unix_stream_socket_[0], iov, 1), 162 SyscallFailsWithErrno(EFAULT)); 163 } 164 165 TEST_F(ReadvSocketTest, BadIovecBase_DgramSocket) { 166 struct iovec iov[1]; 167 iov[0].iov_base = nullptr; 168 iov[0].iov_len = 1024; 169 ASSERT_THAT(readv(test_unix_dgram_socket_[0], iov, 1), 170 SyscallFailsWithErrno(EFAULT)); 171 } 172 173 TEST_F(ReadvSocketTest, ZeroIovecs_StreamSocket) { 174 struct iovec iov[1]; 175 iov[0].iov_base = 0; 176 iov[0].iov_len = 0; 177 ASSERT_THAT(readv(test_unix_stream_socket_[0], iov, 1), SyscallSucceeds()); 178 } 179 180 TEST_F(ReadvSocketTest, ZeroIovecs_DgramSocket) { 181 struct iovec iov[1]; 182 iov[0].iov_base = 0; 183 iov[0].iov_len = 0; 184 ASSERT_THAT(readv(test_unix_dgram_socket_[0], iov, 1), SyscallSucceeds()); 185 } 186 187 TEST_F(ReadvSocketTest, WouldBlock_StreamSocket) { 188 struct iovec iov[1]; 189 iov[0].iov_base = reinterpret_cast<char*>(malloc(kReadvTestDataSize)); 190 iov[0].iov_len = kReadvTestDataSize; 191 ASSERT_THAT(readv(test_unix_stream_socket_[0], iov, 1), 192 SyscallSucceedsWithValue(kReadvTestDataSize)); 193 free(iov[0].iov_base); 194 195 iov[0].iov_base = reinterpret_cast<char*>(malloc(kReadvTestDataSize)); 196 ASSERT_THAT(readv(test_unix_stream_socket_[0], iov, 1), 197 SyscallFailsWithErrno(EAGAIN)); 198 free(iov[0].iov_base); 199 } 200 201 TEST_F(ReadvSocketTest, WouldBlock_DgramSocket) { 202 struct iovec iov[1]; 203 iov[0].iov_base = reinterpret_cast<char*>(malloc(kReadvTestDataSize)); 204 iov[0].iov_len = kReadvTestDataSize; 205 ASSERT_THAT(readv(test_unix_dgram_socket_[0], iov, 1), 206 SyscallSucceedsWithValue(kReadvTestDataSize)); 207 free(iov[0].iov_base); 208 209 iov[0].iov_base = reinterpret_cast<char*>(malloc(kReadvTestDataSize)); 210 ASSERT_THAT(readv(test_unix_dgram_socket_[0], iov, 1), 211 SyscallFailsWithErrno(EAGAIN)); 212 free(iov[0].iov_base); 213 } 214 215 } // namespace 216 217 } // namespace testing 218 } // namespace gvisor