mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
tcp: endpoint.Write has to send all data that has been read from payload
io.Reader.ReadFull returns the number of bytes copied and an error if fewer bytes were read. PiperOrigin-RevId: 360247614
This commit is contained in:
@@ -1552,10 +1552,11 @@ func (e *endpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcp
|
||||
return nil, nil
|
||||
}
|
||||
v := make([]byte, avail)
|
||||
if _, err := io.ReadFull(p, v); err != nil {
|
||||
n, err := p.Read(v)
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, &tcpip.ErrBadBuffer{}
|
||||
}
|
||||
return v, nil
|
||||
return v[:n], nil
|
||||
}()
|
||||
if len(v) == 0 || err != nil {
|
||||
return nil, 0, err
|
||||
|
||||
@@ -2384,6 +2384,7 @@ cc_library(
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/time",
|
||||
gtest,
|
||||
"//test/util:temp_path",
|
||||
"//test/util:test_util",
|
||||
"//test/util:thread_util",
|
||||
],
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "test/syscalls/linux/socket_test_util.h"
|
||||
#include "test/util/temp_path.h"
|
||||
#include "test/util/test_util.h"
|
||||
#include "test/util/thread_util.h"
|
||||
|
||||
@@ -1059,6 +1060,28 @@ TEST_P(TCPSocketPairTest, SpliceToPipe) {
|
||||
SyscallSucceedsWithValue(buf.size()));
|
||||
EXPECT_EQ(memcmp(rbuf.data(), buf.data(), buf.size()), 0);
|
||||
}
|
||||
|
||||
#include <sys/sendfile.h>
|
||||
|
||||
TEST_P(TCPSocketPairTest, SendfileFromRegularFileSucceeds) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
|
||||
const FileDescriptor in_fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDWR));
|
||||
// Fill with some random data.
|
||||
std::vector<char> buf(kPageSize / 2);
|
||||
RandomizeBuffer(buf.data(), buf.size());
|
||||
ASSERT_THAT(pwrite(in_fd.get(), buf.data(), buf.size(), 0),
|
||||
SyscallSucceedsWithValue(buf.size()));
|
||||
|
||||
EXPECT_THAT(
|
||||
sendfile(sockets->first_fd(), in_fd.get(), nullptr, buf.size() + 1),
|
||||
SyscallSucceedsWithValue(buf.size()));
|
||||
std::vector<char> rbuf(buf.size() + 1);
|
||||
ASSERT_THAT(read(sockets->second_fd(), rbuf.data(), rbuf.size()),
|
||||
SyscallSucceedsWithValue(buf.size()));
|
||||
EXPECT_EQ(memcmp(rbuf.data(), buf.data(), buf.size()), 0);
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
TEST_P(TCPSocketPairTest, SetTCPWindowClampBelowMinRcvBufConnectedSocket) {
|
||||
|
||||
Reference in New Issue
Block a user