syscallcompat: OSX: add Unlinkat wrapper
Also, replace remaining naked syscall.Openat calls.
This commit is contained in:
parent
1d7728959c
commit
d8524c7369
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user