pipe: writeLocked has to return ErrWouldBlock if the pipe is full

PiperOrigin-RevId: 356450303
This commit is contained in:
Andrei Vagin
2021-02-09 01:34:45 -08:00
committed by gVisor bot
parent 3f802e7180
commit d6dbe6e5ca
3 changed files with 32 additions and 2 deletions
+3
View File
@@ -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:
+6 -2
View File
@@ -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
}
+23
View File
@@ -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[] =