syscallcompat: Drop Renameat emulation on macOS.

This commit is contained in:
Sebastian Lackner 2019-01-14 02:35:46 +01:00 committed by rfjakob
parent da557702d7
commit 42bf6d1c68
6 changed files with 42 additions and 92 deletions

View File

@ -11,34 +11,6 @@ import (
var chdirMutex sync.Mutex
// emulateRenameat emulates the syscall for platforms that don't have it
// in the kernel (darwin).
func emulateRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) error {
chdirMutex.Lock()
defer chdirMutex.Unlock()
// Unless both paths are absolute we have to save the old working dir and
// Chdir(oldWd) back to it in the end. If we error out before the first
// chdir, Chdir(oldWd) is unneccassary but does no harm.
if !filepath.IsAbs(oldpath) || !filepath.IsAbs(newpath) {
oldWd, err := os.Getwd()
if err != nil {
return err
}
defer os.Chdir(oldWd)
}
// Make oldpath absolute
oldpath, err := dirfdAbs(olddirfd, oldpath)
if err != nil {
return err
}
// Make newpath absolute
newpath, err = dirfdAbs(newdirfd, newpath)
if err != nil {
return err
}
return syscall.Rename(oldpath, newpath)
}
// emulateUnlinkat emulates the syscall for platforms that don't have it
// in the kernel (darwin).
func emulateUnlinkat(dirfd int, path string, flags int) (err error) {
@ -82,24 +54,6 @@ func emulateMknodat(dirfd int, path string, mode uint32, dev int) error {
return syscall.Mknod(path, mode, dev)
}
// dirfdAbs transforms the dirfd-relative "path" to an absolute one. If the
// path is not already absolute, this function will change the working
// directory. The caller has to chdir back.
func dirfdAbs(dirfd int, path string) (string, error) {
if filepath.IsAbs(path) {
return path, nil
}
err := syscall.Fchdir(dirfd)
if err != nil {
return "", err
}
wd, err := os.Getwd()
if err != nil {
return "", err
}
return filepath.Join(wd, path), nil
}
// emulateFchmodat emulates the syscall for platforms that don't have it
// in the kernel (darwin).
func emulateFchmodat(dirfd int, path string, mode uint32, flags int) (err error) {

View File

@ -9,43 +9,6 @@ import (
"golang.org/x/sys/unix"
)
func TestEmulateRenameat(t *testing.T) {
os.Mkdir(tmpDir+"/dir1", 0700)
dir1, err := os.Open(tmpDir + "/dir1")
if err != nil {
t.Fatal(err)
}
defer dir1.Close()
os.Mkdir(tmpDir+"/dir2", 0700)
dir2, err := os.Open(tmpDir + "/dir2")
if err != nil {
t.Fatal(err)
}
defer dir2.Close()
fd, err := os.Create(tmpDir + "/dir1/f1")
if err != nil {
t.Fatal(err)
}
fd.Close()
err = emulateRenameat(int(dir1.Fd()), "f1", int(dir2.Fd()), "f2")
if err != nil {
t.Fatal(err)
}
_, err = os.Stat(tmpDir + "/dir2/f2")
if err != nil {
t.Fatal(err)
}
// Test with absolute path
err = emulateRenameat(-1, tmpDir+"/dir2/f2", -1, tmpDir+"/dir2/f1")
if err != nil {
t.Fatal(err)
}
_, err = os.Stat(tmpDir + "/dir2/f1")
if err != nil {
t.Fatal(err)
}
}
func TestEmulateUnlinkat(t *testing.T) {
os.Mkdir(tmpDir+"/unlink1", 0700)
dirfd, err := os.Open(tmpDir + "/unlink1")

View File

@ -62,6 +62,11 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
return unix.Openat(dirfd, path, flags, mode)
}
// Renameat wraps the Renameat syscall.
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
return unix.Renameat(olddirfd, oldpath, newdirfd, newpath)
}
// Linkat exists both in Linux and in MacOS 10.10+.
func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
return unix.Linkat(olddirfd, oldpath, newdirfd, newpath, flags)

View File

@ -63,6 +63,43 @@ func TestOpenat(t *testing.T) {
}
}
func TestRenameat(t *testing.T) {
os.Mkdir(tmpDir+"/dir1", 0700)
dir1, err := os.Open(tmpDir + "/dir1")
if err != nil {
t.Fatal(err)
}
defer dir1.Close()
os.Mkdir(tmpDir+"/dir2", 0700)
dir2, err := os.Open(tmpDir + "/dir2")
if err != nil {
t.Fatal(err)
}
defer dir2.Close()
fd, err := os.Create(tmpDir + "/dir1/f1")
if err != nil {
t.Fatal(err)
}
fd.Close()
err = Renameat(int(dir1.Fd()), "f1", int(dir2.Fd()), "f2")
if err != nil {
t.Fatal(err)
}
_, err = os.Stat(tmpDir + "/dir2/f2")
if err != nil {
t.Fatal(err)
}
// Test with absolute path
err = Renameat(-1, tmpDir+"/dir2/f2", -1, tmpDir+"/dir2/f1")
if err != nil {
t.Fatal(err)
}
_, err = os.Stat(tmpDir + "/dir2/f1")
if err != nil {
t.Fatal(err)
}
}
func TestFchmodat(t *testing.T) {
regular := "TestFchmodat_Regular"
f, err := os.OpenFile(tmpDir+"/"+regular, os.O_CREATE|os.O_WRONLY, 0000)

View File

@ -72,10 +72,6 @@ func OpenatUser(dirfd int, path string, flags int, mode uint32, context *fuse.Co
return Openat(dirfd, path, flags, mode)
}
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
return emulateRenameat(olddirfd, oldpath, newdirfd, newpath)
}
func Unlinkat(dirfd int, path string, flags int) (err error) {
return emulateUnlinkat(dirfd, path, flags)
}

View File

@ -80,11 +80,6 @@ func OpenatUser(dirfd int, path string, flags int, mode uint32, context *fuse.Co
return Openat(dirfd, path, flags, mode)
}
// Renameat wraps the Renameat syscall.
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
return syscall.Renameat(olddirfd, oldpath, newdirfd, newpath)
}
// Unlinkat syscall.
func Unlinkat(dirfd int, path string, flags int) (err error) {
return unix.Unlinkat(dirfd, path, flags)