summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/vfs
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-12-05 03:16:38 +0000
committergVisor bot <gvisor-bot@google.com>2020-12-05 03:16:38 +0000
commit8a9c95395dc28321dfdf43297eda1c90ef8aeff9 (patch)
tree574daf88ebacd40d42003900894b4b9558764464 /pkg/sentry/vfs
parent84ffd9bfe74f39dfacd655b511cd336ba08e2f21 (diff)
parentb80021afd2395fd40464ebbeac8f4c8034dee06e (diff)
Merge release-20201130.0-45-gb80021afd (automated)
Diffstat (limited to 'pkg/sentry/vfs')
-rw-r--r--pkg/sentry/vfs/file_description.go26
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
+ }
+ }
+}