mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
pipe: writeLocked has to return ErrWouldBlock if the pipe is full
PiperOrigin-RevId: 356450303
This commit is contained in:
@@ -656,6 +656,9 @@ func (rw *regularFileReadWriter) WriteFromBlocks(srcs safemem.BlockSeq) (uint64,
|
||||
|
||||
// Write to that memory as usual.
|
||||
seg, gap = rw.file.data.Insert(gap, gapMR, fr.Start), fsutil.FileRangeGapIterator{}
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
exitLoop:
|
||||
|
||||
@@ -247,11 +247,15 @@ func (p *Pipe) writeLocked(count int64, f func(safemem.BlockSeq) (uint64, error)
|
||||
return 0, syscall.EPIPE
|
||||
}
|
||||
|
||||
// POSIX requires that a write smaller than atomicIOBytes (PIPE_BUF) be
|
||||
// atomic, but requires no atomicity for writes larger than this.
|
||||
avail := p.max - p.size
|
||||
if avail == 0 {
|
||||
return 0, syserror.ErrWouldBlock
|
||||
}
|
||||
short := false
|
||||
if count > avail {
|
||||
// POSIX requires that a write smaller than atomicIOBytes
|
||||
// (PIPE_BUF) be atomic, but requires no atomicity for writes
|
||||
// larger than this.
|
||||
if count <= atomicIOBytes {
|
||||
return 0, syserror.ErrWouldBlock
|
||||
}
|
||||
|
||||
@@ -551,6 +551,29 @@ TEST(SendFileTest, SendPipeEOF) {
|
||||
SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
TEST(SendFileTest, SendToFullPipeReturnsEAGAIN) {
|
||||
// Create and open an empty input file.
|
||||
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));
|
||||
|
||||
// Set up the output pipe.
|
||||
int fds[2];
|
||||
ASSERT_THAT(pipe2(fds, O_NONBLOCK), SyscallSucceeds());
|
||||
const FileDescriptor rfd(fds[0]);
|
||||
const FileDescriptor wfd(fds[1]);
|
||||
|
||||
int pipe_size = -1;
|
||||
ASSERT_THAT(pipe_size = fcntl(wfd.get(), F_GETPIPE_SZ), SyscallSucceeds());
|
||||
int data_size = pipe_size * 8;
|
||||
ASSERT_THAT(ftruncate(in_fd.get(), data_size), SyscallSucceeds());
|
||||
|
||||
ASSERT_THAT(sendfile(wfd.get(), in_fd.get(), 0, data_size),
|
||||
SyscallSucceeds());
|
||||
EXPECT_THAT(sendfile(wfd.get(), in_fd.get(), 0, data_size),
|
||||
SyscallFailsWithErrno(EAGAIN));
|
||||
}
|
||||
|
||||
TEST(SendFileTest, SendPipeBlocks) {
|
||||
// Create temp file.
|
||||
constexpr char kData[] =
|
||||
|
||||
Reference in New Issue
Block a user