syscallcompat: OSX: add Unlinkat wrapper

Also, replace remaining naked syscall.Openat calls.
This commit is contained in:
Jakob Unterwurzacher 2016-07-03 20:17:40 +02:00
parent 1d7728959c
commit d8524c7369
6 changed files with 32 additions and 8 deletions

View File

@ -133,7 +133,7 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte
// Create content
var fdRaw int
fdRaw, err = syscall.Openat(int(dirfd.Fd()), cName, iflags|os.O_CREATE, mode)
fdRaw, err = syscallcompat.Openat(int(dirfd.Fd()), cName, iflags|os.O_CREATE, mode)
if err != nil {
nametransform.DeleteLongName(dirfd, cName)
return nil, fuse.ToStatus(err)
@ -295,7 +295,7 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) {
}
defer dirfd.Close()
// Delete content
err = syscall.Unlinkat(int(dirfd.Fd()), cName)
err = syscallcompat.Unlinkat(int(dirfd.Fd()), cName)
if err != nil {
return fuse.ToStatus(err)
}

View File

@ -114,7 +114,7 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {
defer parentDirFd.Close()
cName := filepath.Base(cPath)
dirfdRaw, err := syscall.Openat(int(parentDirFd.Fd()), cName,
dirfdRaw, err := syscallcompat.Openat(int(parentDirFd.Fd()), cName,
syscall.O_RDONLY, 0)
if err == syscall.EACCES {
// We need permission to read and modify the directory
@ -136,7 +136,7 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {
// Retry open
var st syscall.Stat_t
syscall.Lstat(cPath, &st)
dirfdRaw, err = syscall.Openat(int(parentDirFd.Fd()), cName,
dirfdRaw, err = syscallcompat.Openat(int(parentDirFd.Fd()), cName,
syscall.O_RDONLY, 0)
// Undo the chmod if removing the directory failed
defer func() {
@ -191,7 +191,7 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(err)
}
// Delete "gocryptfs.diriv.rmdir.XYZ"
err = syscall.Unlinkat(int(parentDirFd.Fd()), tmpName)
err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), tmpName)
if err != nil {
tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
}

View File

@ -9,6 +9,7 @@ import (
"syscall"
"github.com/rfjakob/gocryptfs/internal/cryptocore"
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
"github.com/rfjakob/gocryptfs/internal/tlog"
)
@ -35,7 +36,7 @@ func ReadDirIV(dir string) (iv []byte, err error) {
// ReadDirIVAt reads "gocryptfs.diriv" from the directory that is opened as "dirfd".
// Using the dirfd makes it immune to concurrent renames of the directory.
func ReadDirIVAt(dirfd *os.File) (iv []byte, err error) {
fdRaw, err := syscall.Openat(int(dirfd.Fd()), DirIVFilename, syscall.O_RDONLY, 0)
fdRaw, err := syscallcompat.Openat(int(dirfd.Fd()), DirIVFilename, syscall.O_RDONLY, 0)
if err != nil {
tlog.Warn.Printf("ReadDirIVAt: opening %q in dir %q failed: %v",
DirIVFilename, dirfd.Name(), err)

View File

@ -9,6 +9,7 @@ import (
"strings"
"syscall"
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
"github.com/rfjakob/gocryptfs/internal/tlog"
)
@ -65,7 +66,7 @@ func ReadLongName(path string) (string, error) {
// DeleteLongName deletes "hashName.name".
func DeleteLongName(dirfd *os.File, hashName string) error {
err := syscall.Unlinkat(int(dirfd.Fd()), hashName+LongNameSuffix)
err := syscallcompat.Unlinkat(int(dirfd.Fd()), hashName+LongNameSuffix)
if err != nil {
tlog.Warn.Printf("DeleteLongName: %v", err)
}
@ -86,7 +87,7 @@ func (n *NameTransform) WriteLongName(dirfd *os.File, hashName string, plainName
cName := n.EncryptName(plainName, dirIV)
// Write the encrypted name into hashName.name
fdRaw, err := syscall.Openat(int(dirfd.Fd()), hashName+LongNameSuffix,
fdRaw, err := syscallcompat.Openat(int(dirfd.Fd()), hashName+LongNameSuffix,
syscall.O_WRONLY|syscall.O_CREAT|syscall.O_EXCL, 0600)
if err != nil {
tlog.Warn.Printf("WriteLongName: Openat: %v", err)

View File

@ -69,6 +69,24 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e
return syscall.Rename(oldpath, newpath)
}
// Poor man's Unlinkat
func Unlinkat(dirfd int, path string) (err error) {
chdirMutex.Lock()
defer chdirMutex.Unlock()
if !filepath.IsAbs(path) {
oldWd, err := os.Getwd()
if err != nil {
return err
}
defer os.Chdir(oldWd)
}
path, err = dirfdAbs(dirfd, path)
if err != nil {
return err
}
return syscall.Unlink(path)
}
// 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.

View File

@ -48,3 +48,7 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
return syscall.Renameat(olddirfd, oldpath, newdirfd, newpath)
}
func Unlinkat(dirfd int, path string) error {
return syscall.Unlinkat(dirfd, path)
}