From 7b0d56fe98a4ae449d26af0b83d00271a179db6e Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 14 Jan 2019 02:51:50 +0100 Subject: [PATCH] syscallcompat: Drop Symlinkat emulation on macOS. --- internal/syscallcompat/emulate.go | 20 ----------- internal/syscallcompat/emulate_test.go | 41 ----------------------- internal/syscallcompat/sys_common.go | 5 +++ internal/syscallcompat/sys_common_test.go | 40 ++++++++++++++++++++++ internal/syscallcompat/sys_darwin.go | 4 --- internal/syscallcompat/sys_linux.go | 5 --- 6 files changed, 45 insertions(+), 70 deletions(-) diff --git a/internal/syscallcompat/emulate.go b/internal/syscallcompat/emulate.go index dc8cf6d..a98a0ce 100644 --- a/internal/syscallcompat/emulate.go +++ b/internal/syscallcompat/emulate.go @@ -30,26 +30,6 @@ func emulateMknodat(dirfd int, path string, mode uint32, dev int) error { return syscall.Mknod(path, mode, dev) } -// emulateSymlinkat emulates the syscall for platforms that don't have it -// in the kernel (darwin). -func emulateSymlinkat(oldpath string, newdirfd int, newpath string) (err error) { - if !filepath.IsAbs(newpath) { - 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(newdirfd) - if err != nil { - return err - } - defer syscall.Fchdir(cwd) - } - return syscall.Symlink(oldpath, newpath) -} - // emulateMkdirat emulates the syscall for platforms that don't have it // in the kernel (darwin). func emulateMkdirat(dirfd int, path string, mode uint32) (err error) { diff --git a/internal/syscallcompat/emulate_test.go b/internal/syscallcompat/emulate_test.go index 6fe5f3e..6db37f8 100644 --- a/internal/syscallcompat/emulate_test.go +++ b/internal/syscallcompat/emulate_test.go @@ -2,8 +2,6 @@ package syscallcompat import ( "os" - "runtime" - "syscall" "testing" "golang.org/x/sys/unix" @@ -29,45 +27,6 @@ func TestEmulateMknodat(t *testing.T) { } } -// symlinkCheckMode looks if the mode bits in "st" say that this is a symlink. -// Calls t.Fatal() if not. -func symlinkCheckMode(t *testing.T, st syscall.Stat_t) { - if runtime.GOOS == "darwin" { - // On MacOS, symlinks don't carry their own permissions, so - // only check the file type. - if st.Mode&syscall.S_IFMT != syscall.S_IFLNK { - t.Fatalf("This is not a symlink: mode = 0%o", st.Mode) - } - return - } - if st.Mode != 0120777 { - t.Fatalf("Wrong mode, have 0%o, want 0120777", st.Mode) - } -} - -func TestEmulateSymlinkat(t *testing.T) { - err := emulateSymlinkat("/foo/bar/baz", tmpDirFd, "symlink1") - if err != nil { - t.Fatal(err) - } - var st syscall.Stat_t - err = syscall.Lstat(tmpDir+"/symlink1", &st) - if err != nil { - t.Fatal(err) - } - symlinkCheckMode(t, st) - // Test with absolute path - err = emulateSymlinkat("/foo/bar/baz", -1, tmpDir+"/symlink2") - if err != nil { - t.Fatal(err) - } - err = syscall.Lstat(tmpDir+"/symlink2", &st) - if err != nil { - t.Fatal(err) - } - symlinkCheckMode(t, st) -} - func TestEmulateMkdirat(t *testing.T) { err := emulateMkdirat(tmpDirFd, "mkdirat", 0700) if err != nil { diff --git a/internal/syscallcompat/sys_common.go b/internal/syscallcompat/sys_common.go index 9514830..21bac56 100644 --- a/internal/syscallcompat/sys_common.go +++ b/internal/syscallcompat/sys_common.go @@ -87,6 +87,11 @@ func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags in return unix.Linkat(olddirfd, oldpath, newdirfd, newpath, flags) } +// Symlinkat syscall. +func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { + return unix.Symlinkat(oldpath, newdirfd, newpath) +} + 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 4556279..78283e6 100644 --- a/internal/syscallcompat/sys_common_test.go +++ b/internal/syscallcompat/sys_common_test.go @@ -3,6 +3,7 @@ package syscallcompat import ( "bytes" "os" + "runtime" "syscall" "testing" @@ -207,3 +208,42 @@ func TestFchmodat(t *testing.T) { t.Errorf("chmod on symlink affected symlink target: New mode=%#0o", st.Mode) } } + +// symlinkCheckMode looks if the mode bits in "st" say that this is a symlink. +// Calls t.Fatal() if not. +func symlinkCheckMode(t *testing.T, st syscall.Stat_t) { + if runtime.GOOS == "darwin" { + // On MacOS, symlinks don't carry their own permissions, so + // only check the file type. + if st.Mode&syscall.S_IFMT != syscall.S_IFLNK { + t.Fatalf("This is not a symlink: mode = 0%o", st.Mode) + } + return + } + if st.Mode != 0120777 { + t.Fatalf("Wrong mode, have 0%o, want 0120777", st.Mode) + } +} + +func TestSymlinkat(t *testing.T) { + err := Symlinkat("/foo/bar/baz", tmpDirFd, "symlink1") + if err != nil { + t.Fatal(err) + } + var st syscall.Stat_t + err = syscall.Lstat(tmpDir+"/symlink1", &st) + if err != nil { + t.Fatal(err) + } + symlinkCheckMode(t, st) + // Test with absolute path + err = Symlinkat("/foo/bar/baz", -1, tmpDir+"/symlink2") + if err != nil { + t.Fatal(err) + } + err = syscall.Lstat(tmpDir+"/symlink2", &st) + if err != nil { + t.Fatal(err) + } + symlinkCheckMode(t, st) +} diff --git a/internal/syscallcompat/sys_darwin.go b/internal/syscallcompat/sys_darwin.go index be85fee..2780ef6 100644 --- a/internal/syscallcompat/sys_darwin.go +++ b/internal/syscallcompat/sys_darwin.go @@ -102,10 +102,6 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { return unix.Fchmodat(dirfd, path, mode, flags) } -func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { - return emulateSymlinkat(oldpath, newdirfd, newpath) -} - func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.Context) (err error) { if context != nil { runtime.LockOSThread() diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go index cacec6a..0b34aa1 100644 --- a/internal/syscallcompat/sys_linux.go +++ b/internal/syscallcompat/sys_linux.go @@ -154,11 +154,6 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { return syscall.Chmod(procPath, mode) } -// Symlinkat syscall. -func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { - return unix.Symlinkat(oldpath, newdirfd, newpath) -} - // SymlinkatUser runs the Symlinkat syscall in the context of a different user. func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.Context) (err error) { if context != nil {