diff options
author | gVisor bot <gvisor-bot@google.com> | 2020-12-05 03:16:38 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-12-05 03:16:38 +0000 |
commit | 8a9c95395dc28321dfdf43297eda1c90ef8aeff9 (patch) | |
tree | 574daf88ebacd40d42003900894b4b9558764464 /pkg/sentry/vfs | |
parent | 84ffd9bfe74f39dfacd655b511cd336ba08e2f21 (diff) | |
parent | b80021afd2395fd40464ebbeac8f4c8034dee06e (diff) |
Merge release-20201130.0-45-gb80021afd (automated)
Diffstat (limited to 'pkg/sentry/vfs')
-rw-r--r-- | pkg/sentry/vfs/file_description.go | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/pkg/sentry/vfs/file_description.go b/pkg/sentry/vfs/file_description.go index 2153382e9..5321ac80a 100644 --- a/pkg/sentry/vfs/file_description.go +++ b/pkg/sentry/vfs/file_description.go @@ -15,6 +15,7 @@ package vfs import ( + "io" "sync/atomic" "gvisor.dev/gvisor/pkg/abi/linux" @@ -838,3 +839,28 @@ func (fd *FileDescription) SetAsyncHandler(newHandler func() FileAsync) FileAsyn } return fd.asyncHandler } + +// CopyRegularFileData copies data from srcFD to dstFD until reading from srcFD +// returns EOF or an error. It returns the number of bytes copied. +func CopyRegularFileData(ctx context.Context, dstFD, srcFD *FileDescription) (int64, error) { + done := int64(0) + buf := usermem.BytesIOSequence(make([]byte, 32*1024)) // arbitrary buffer size + for { + readN, readErr := srcFD.Read(ctx, buf, ReadOptions{}) + if readErr != nil && readErr != io.EOF { + return done, readErr + } + src := buf.TakeFirst64(readN) + for src.NumBytes() != 0 { + writeN, writeErr := dstFD.Write(ctx, src, WriteOptions{}) + done += writeN + src = src.DropFirst64(writeN) + if writeErr != nil { + return done, writeErr + } + } + if readErr == io.EOF { + return done, nil + } + } +} |