aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/syscallcompat/emulate.go22
-rw-r--r--internal/syscallcompat/emulate_test.go35
-rw-r--r--internal/syscallcompat/sys_common.go10
-rw-r--r--internal/syscallcompat/sys_common_test.go35
-rw-r--r--internal/syscallcompat/sys_darwin.go4
-rw-r--r--internal/syscallcompat/sys_linux.go10
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)