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
|
// Create content
|
||||||
var fdRaw int
|
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 {
|
if err != nil {
|
||||||
nametransform.DeleteLongName(dirfd, cName)
|
nametransform.DeleteLongName(dirfd, cName)
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
|
@ -295,7 +295,7 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) {
|
||||||
}
|
}
|
||||||
defer dirfd.Close()
|
defer dirfd.Close()
|
||||||
// Delete content
|
// Delete content
|
||||||
err = syscall.Unlinkat(int(dirfd.Fd()), cName)
|
err = syscallcompat.Unlinkat(int(dirfd.Fd()), cName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {
|
||||||
defer parentDirFd.Close()
|
defer parentDirFd.Close()
|
||||||
|
|
||||||
cName := filepath.Base(cPath)
|
cName := filepath.Base(cPath)
|
||||||
dirfdRaw, err := syscall.Openat(int(parentDirFd.Fd()), cName,
|
dirfdRaw, err := syscallcompat.Openat(int(parentDirFd.Fd()), cName,
|
||||||
syscall.O_RDONLY, 0)
|
syscall.O_RDONLY, 0)
|
||||||
if err == syscall.EACCES {
|
if err == syscall.EACCES {
|
||||||
// We need permission to read and modify the directory
|
// 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
|
// Retry open
|
||||||
var st syscall.Stat_t
|
var st syscall.Stat_t
|
||||||
syscall.Lstat(cPath, &st)
|
syscall.Lstat(cPath, &st)
|
||||||
dirfdRaw, err = syscall.Openat(int(parentDirFd.Fd()), cName,
|
dirfdRaw, err = syscallcompat.Openat(int(parentDirFd.Fd()), cName,
|
||||||
syscall.O_RDONLY, 0)
|
syscall.O_RDONLY, 0)
|
||||||
// Undo the chmod if removing the directory failed
|
// Undo the chmod if removing the directory failed
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -191,7 +191,7 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Delete "gocryptfs.diriv.rmdir.XYZ"
|
// Delete "gocryptfs.diriv.rmdir.XYZ"
|
||||||
err = syscall.Unlinkat(int(parentDirFd.Fd()), tmpName)
|
err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), tmpName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
|
tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"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".
|
// ReadDirIVAt reads "gocryptfs.diriv" from the directory that is opened as "dirfd".
|
||||||
// Using the dirfd makes it immune to concurrent renames of the directory.
|
// Using the dirfd makes it immune to concurrent renames of the directory.
|
||||||
func ReadDirIVAt(dirfd *os.File) (iv []byte, err error) {
|
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 {
|
if err != nil {
|
||||||
tlog.Warn.Printf("ReadDirIVAt: opening %q in dir %q failed: %v",
|
tlog.Warn.Printf("ReadDirIVAt: opening %q in dir %q failed: %v",
|
||||||
DirIVFilename, dirfd.Name(), err)
|
DirIVFilename, dirfd.Name(), err)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ func ReadLongName(path string) (string, error) {
|
||||||
|
|
||||||
// DeleteLongName deletes "hashName.name".
|
// DeleteLongName deletes "hashName.name".
|
||||||
func DeleteLongName(dirfd *os.File, hashName string) error {
|
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 {
|
if err != nil {
|
||||||
tlog.Warn.Printf("DeleteLongName: %v", err)
|
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)
|
cName := n.EncryptName(plainName, dirIV)
|
||||||
|
|
||||||
// Write the encrypted name into hashName.name
|
// 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)
|
syscall.O_WRONLY|syscall.O_CREAT|syscall.O_EXCL, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Warn.Printf("WriteLongName: Openat: %v", err)
|
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)
|
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
|
// dirfdAbs transforms the dirfd-relative "path" to an absolute one. If the
|
||||||
// path is not already absolute, this function will change the working
|
// path is not already absolute, this function will change the working
|
||||||
// directory. The caller has to chdir back.
|
// 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) {
|
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
|
||||||
return syscall.Renameat(olddirfd, oldpath, newdirfd, newpath)
|
return syscall.Renameat(olddirfd, oldpath, newdirfd, newpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Unlinkat(dirfd int, path string) error {
|
||||||
|
return syscall.Unlinkat(dirfd, path)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue