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) | 
