diff options
Diffstat (limited to 'internal/syscallcompat')
-rw-r--r-- | internal/syscallcompat/emulate.go | 22 | ||||
-rw-r--r-- | internal/syscallcompat/emulate_test.go | 35 | ||||
-rw-r--r-- | internal/syscallcompat/sys_common.go | 10 | ||||
-rw-r--r-- | internal/syscallcompat/sys_common_test.go | 35 | ||||
-rw-r--r-- | internal/syscallcompat/sys_darwin.go | 4 | ||||
-rw-r--r-- | internal/syscallcompat/sys_linux.go | 10 |
6 files changed, 45 insertions, 71 deletions
diff --git a/internal/syscallcompat/emulate.go b/internal/syscallcompat/emulate.go index 7bed31a..91b592b 100644 --- a/internal/syscallcompat/emulate.go +++ b/internal/syscallcompat/emulate.go @@ -4,8 +4,6 @@ import ( "path/filepath" "sync" "syscall" - - "golang.org/x/sys/unix" ) var chdirMutex sync.Mutex @@ -29,23 +27,3 @@ func emulateMknodat(dirfd int, path string, mode uint32, dev int) error { } return syscall.Mknod(path, mode, dev) } - -// emulateFstatat emulates the syscall for platforms that don't have it -// in the kernel (darwin). -func emulateFstatat(dirfd int, path string, stat *unix.Stat_t, flags int) (err error) { - if !filepath.IsAbs(path) { - chdirMutex.Lock() - defer chdirMutex.Unlock() - cwd, err := syscall.Open(".", syscall.O_RDONLY, 0) - if err != nil { - return err - } - defer syscall.Close(cwd) - err = syscall.Fchdir(dirfd) - if err != nil { - return err - } - defer syscall.Fchdir(cwd) - } - return unix.Lstat(path, stat) -} diff --git a/internal/syscallcompat/emulate_test.go b/internal/syscallcompat/emulate_test.go index eeffebf..16383f2 100644 --- a/internal/syscallcompat/emulate_test.go +++ b/internal/syscallcompat/emulate_test.go @@ -26,38 +26,3 @@ func TestEmulateMknodat(t *testing.T) { t.Fatal(err) } } - -func TestEmulateFstatat(t *testing.T) { - var st unix.Stat_t - // stat a normal file (size 3) - f, err := os.Create(tmpDir + "/fstatat") - if err != nil { - t.Fatal(err) - } - _, err = f.Write([]byte("foo")) - if err != nil { - t.Fatal(err) - } - f.Close() - err = emulateFstatat(tmpDirFd, "fstatat", &st, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - t.Fatal(err) - } - if st.Size != 3 { - t.Errorf("wrong file size: %d", st.Size) - } - // stat a symlink and check that the size matches the length of the - // symlink target. This proves that we have stat'ed the symlink itself. - err = os.Symlink(tmpDir+"/fstatat", tmpDir+"/fstatatSymlink") - if err != nil { - t.Fatal(err) - } - err = emulateFstatat(tmpDirFd, "fstatatSymlink", &st, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - t.Fatal(err) - } - expectedSize := int64(len(tmpDir + "/fstatat")) - if st.Size != expectedSize { - t.Errorf("symlink size: expected=%d, got=%d", expectedSize, st.Size) - } -} diff --git a/internal/syscallcompat/sys_common.go b/internal/syscallcompat/sys_common.go index 577e2ed..b6bbdff 100644 --- a/internal/syscallcompat/sys_common.go +++ b/internal/syscallcompat/sys_common.go @@ -97,6 +97,16 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) { return unix.Mkdirat(dirfd, path, mode) } +// Fstatat syscall. +func Fstatat(dirfd int, path string, stat *unix.Stat_t, flags int) (err error) { + // Why would we ever want to call this without AT_SYMLINK_NOFOLLOW? + if flags&unix.AT_SYMLINK_NOFOLLOW == 0 { + tlog.Warn.Printf("Fstatat: adding missing AT_SYMLINK_NOFOLLOW flag") + flags |= unix.AT_SYMLINK_NOFOLLOW + } + return unix.Fstatat(dirfd, path, stat, flags) +} + const XATTR_SIZE_MAX = 65536 // Make the buffer 1kB bigger so we can detect overflows diff --git a/internal/syscallcompat/sys_common_test.go b/internal/syscallcompat/sys_common_test.go index e1c7b24..14e1b3f 100644 --- a/internal/syscallcompat/sys_common_test.go +++ b/internal/syscallcompat/sys_common_test.go @@ -273,3 +273,38 @@ func TestMkdirat(t *testing.T) { t.Fatalf("mkdirat did not create a directory") } } + +func TestFstatat(t *testing.T) { + var st unix.Stat_t + // stat a normal file (size 3) + f, err := os.Create(tmpDir + "/fstatat") + if err != nil { + t.Fatal(err) + } + _, err = f.Write([]byte("foo")) + if err != nil { + t.Fatal(err) + } + f.Close() + err = Fstatat(tmpDirFd, "fstatat", &st, unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + t.Fatal(err) + } + if st.Size != 3 { + t.Errorf("wrong file size: %d", st.Size) + } + // stat a symlink and check that the size matches the length of the + // symlink target. This proves that we have stat'ed the symlink itself. + err = os.Symlink(tmpDir+"/fstatat", tmpDir+"/fstatatSymlink") + if err != nil { + t.Fatal(err) + } + err = Fstatat(tmpDirFd, "fstatatSymlink", &st, unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + t.Fatal(err) + } + expectedSize := int64(len(tmpDir + "/fstatat")) + if st.Size != expectedSize { + t.Errorf("symlink size: expected=%d, got=%d", expectedSize, st.Size) + } +} diff --git a/internal/syscallcompat/sys_darwin.go b/internal/syscallcompat/sys_darwin.go index 3b27560..b8b82c8 100644 --- a/internal/syscallcompat/sys_darwin.go +++ b/internal/syscallcompat/sys_darwin.go @@ -132,10 +132,6 @@ func MkdiratUser(dirfd int, path string, mode uint32, context *fuse.Context) (er return Mkdirat(dirfd, path, mode) } -func Fstatat(dirfd int, path string, stat *unix.Stat_t, flags int) (err error) { - return emulateFstatat(dirfd, path, stat, flags) -} - func Getdents(fd int) ([]fuse.DirEntry, error) { return emulateGetdents(fd) } diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go index 21e07c9..e662001 100644 --- a/internal/syscallcompat/sys_linux.go +++ b/internal/syscallcompat/sys_linux.go @@ -198,16 +198,6 @@ func MkdiratUser(dirfd int, path string, mode uint32, context *fuse.Context) (er return Mkdirat(dirfd, path, mode) } -// Fstatat syscall. -func Fstatat(dirfd int, path string, stat *unix.Stat_t, flags int) (err error) { - // Why would we ever want to call this without AT_SYMLINK_NOFOLLOW? - if flags&unix.AT_SYMLINK_NOFOLLOW == 0 { - tlog.Warn.Printf("Fstatat: adding missing AT_SYMLINK_NOFOLLOW flag") - flags |= unix.AT_SYMLINK_NOFOLLOW - } - return unix.Fstatat(dirfd, path, stat, flags) -} - // Getdents syscall. func Getdents(fd int) ([]fuse.DirEntry, error) { return getdents(fd) |