summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/fusefrontend/fs.go4
-rw-r--r--internal/fusefrontend/fs_dir.go6
-rw-r--r--internal/nametransform/diriv.go3
-rw-r--r--internal/nametransform/longnames.go5
-rw-r--r--internal/syscallcompat/sys_darwin.go18
-rw-r--r--internal/syscallcompat/sys_linux.go4
6 files changed, 32 insertions, 8 deletions
diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go
index 561af8f..279c755 100644
--- a/internal/fusefrontend/fs.go
+++ b/internal/fusefrontend/fs.go
@@ -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)
}
diff --git a/internal/fusefrontend/fs_dir.go b/internal/fusefrontend/fs_dir.go
index 699ec7b..ab97932 100644
--- a/internal/fusefrontend/fs_dir.go
+++ b/internal/fusefrontend/fs_dir.go
@@ -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)
}
diff --git a/internal/nametransform/diriv.go b/internal/nametransform/diriv.go
index b9473aa..51af1c3 100644
--- a/internal/nametransform/diriv.go
+++ b/internal/nametransform/diriv.go
@@ -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)
diff --git a/internal/nametransform/longnames.go b/internal/nametransform/longnames.go
index 13bedb3..cf7f34c 100644
--- a/internal/nametransform/longnames.go
+++ b/internal/nametransform/longnames.go
@@ -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)
diff --git a/internal/syscallcompat/sys_darwin.go b/internal/syscallcompat/sys_darwin.go
index 7d39484..6300317 100644
--- a/internal/syscallcompat/sys_darwin.go
+++ b/internal/syscallcompat/sys_darwin.go
@@ -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.
diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go
index e12d100..ded5d17 100644
--- a/internal/syscallcompat/sys_linux.go
+++ b/internal/syscallcompat/sys_linux.go
@@ -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)
+}