aboutsummaryrefslogtreecommitdiff
path: root/internal/syscallcompat/getdents_other.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/syscallcompat/getdents_other.go')
-rw-r--r--internal/syscallcompat/getdents_other.go50
1 files changed, 31 insertions, 19 deletions
diff --git a/internal/syscallcompat/getdents_other.go b/internal/syscallcompat/getdents_other.go
index 82932db..1ed5ecf 100644
--- a/internal/syscallcompat/getdents_other.go
+++ b/internal/syscallcompat/getdents_other.go
@@ -9,27 +9,11 @@ import (
"github.com/hanwen/go-fuse/v2/fuse"
)
-// emulateGetdents reads all directory entries from the open directory "fd"
-// and returns them in a fuse.DirEntry slice.
-func emulateGetdents(fd int) (out []fuse.DirEntry, err error) {
- // os.File closes the fd in its finalizer. Duplicate the fd to not affect
- // the original fd.
- newFd, err := syscall.Dup(fd)
- if err != nil {
- return nil, err
- }
- f := os.NewFile(uintptr(newFd), "")
- defer f.Close()
- // Get all file names in the directory
- names, err := f.Readdirnames(0)
- if err != nil {
- return nil, err
- }
- // Stat all of them and convert to fuse.DirEntry
- out = make([]fuse.DirEntry, 0, len(names))
+func fillDirEntries(fd int, names []string) ([]fuse.DirEntry, error) {
+ out := make([]fuse.DirEntry, 0, len(names))
for _, name := range names {
var st unix.Stat_t
- err = Fstatat(fd, name, &st, unix.AT_SYMLINK_NOFOLLOW)
+ err := Fstatat(fd, name, &st, unix.AT_SYMLINK_NOFOLLOW)
if err == syscall.ENOENT {
// File disappeared between readdir and stat. Pretend we did not
// see it.
@@ -47,3 +31,31 @@ func emulateGetdents(fd int) (out []fuse.DirEntry, err error) {
}
return out, nil
}
+
+// emulateGetdents reads all directory entries from the open directory "fd"
+// and returns normal entries and "." / ".." split into two slices.
+func emulateGetdents(fd int) (out []fuse.DirEntry, outSpecial []fuse.DirEntry, err error) {
+ // os.File closes the fd in its finalizer. Duplicate the fd to not affect
+ // the original fd.
+ newFd, err := syscall.Dup(fd)
+ if err != nil {
+ return nil, nil, err
+ }
+ f := os.NewFile(uintptr(newFd), "")
+ defer f.Close()
+ // Get all file names in the directory
+ names, err := f.Readdirnames(0)
+ if err != nil {
+ return nil, nil, err
+ }
+ // Stat all the names and convert to fuse.DirEntry
+ out, err = fillDirEntries(fd, names)
+ if err != nil {
+ return nil, nil, err
+ }
+ outSpecial, err = fillDirEntries(fd, []string{".", ".."})
+ if err != nil {
+ return nil, nil, err
+ }
+ return out, outSpecial, nil
+}