18600: Merge branch 'main'
[arvados.git] / sdk / go / arvados / fs_filehandle.go
index 56963b64a5cbf89617245fa117fb9871fa44a46c..f50dd4612b1385f74de6c8de205b29dd01c622ec 100644 (file)
@@ -1,7 +1,12 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: Apache-2.0
+
 package arvados
 
 import (
        "io"
+       "io/fs"
        "os"
 )
 
@@ -69,15 +74,44 @@ func (f *filehandle) Write(p []byte) (n int, err error) {
        return
 }
 
+// dirEntry implements fs.DirEntry, see (*filehandle)ReadDir().
+type dirEntry struct {
+       os.FileInfo
+}
+
+func (ent dirEntry) Type() fs.FileMode {
+       return ent.Mode().Type()
+}
+func (ent dirEntry) Info() (fs.FileInfo, error) {
+       return ent, nil
+}
+
+// ReadDir implements fs.ReadDirFile.
+func (f *filehandle) ReadDir(count int) ([]fs.DirEntry, error) {
+       fis, err := f.Readdir(count)
+       if len(fis) == 0 {
+               return nil, err
+       }
+       ents := make([]fs.DirEntry, len(fis))
+       for i, fi := range fis {
+               ents[i] = dirEntry{fi}
+       }
+       return ents, err
+}
+
 func (f *filehandle) Readdir(count int) ([]os.FileInfo, error) {
        if !f.inode.IsDir() {
                return nil, ErrInvalidOperation
        }
        if count <= 0 {
-               return f.inode.Readdir(), nil
+               return f.inode.Readdir()
        }
        if f.unreaddirs == nil {
-               f.unreaddirs = f.inode.Readdir()
+               var err error
+               f.unreaddirs, err = f.inode.Readdir()
+               if err != nil {
+                       return nil, err
+               }
        }
        if len(f.unreaddirs) == 0 {
                return nil, io.EOF
@@ -97,3 +131,23 @@ func (f *filehandle) Stat() (os.FileInfo, error) {
 func (f *filehandle) Close() error {
        return nil
 }
+
+func (f *filehandle) Sync() error {
+       // Sync the containing filesystem.
+       return f.FS().Sync()
+}
+
+func (f *filehandle) Snapshot() (*Subtree, error) {
+       if !f.readable {
+               return nil, ErrInvalidOperation
+       }
+       node, err := f.inode.Snapshot()
+       return &Subtree{inode: node}, err
+}
+
+func (f *filehandle) Splice(r *Subtree) error {
+       if !f.writable {
+               return ErrReadOnlyFile
+       }
+       return f.inode.Splice(r.inode)
+}