summaryrefslogtreecommitdiff
path: root/internal/syscallcompat
diff options
context:
space:
mode:
Diffstat (limited to 'internal/syscallcompat')
-rw-r--r--internal/syscallcompat/sys_darwin.go23
-rw-r--r--internal/syscallcompat/sys_linux.go16
2 files changed, 27 insertions, 12 deletions
diff --git a/internal/syscallcompat/sys_darwin.go b/internal/syscallcompat/sys_darwin.go
index 4068e1a..527598b 100644
--- a/internal/syscallcompat/sys_darwin.go
+++ b/internal/syscallcompat/sys_darwin.go
@@ -6,6 +6,8 @@ import (
"path/filepath"
"sync"
"syscall"
+
+ "golang.org/x/sys/unix"
)
// Sorry, fallocate is not available on OSX at all and
@@ -71,21 +73,24 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) error
}
// Poor man's Unlinkat
-func Unlinkat(dirfd int, path string) error {
+func Unlinkat(dirfd int, path string, flags int) (err error) {
chdirMutex.Lock()
defer chdirMutex.Unlock()
- if !filepath.IsAbs(path) {
- oldWd, err := os.Getwd()
- if err != nil {
- return err
- }
- defer os.Chdir(oldWd)
+ cwd, err := syscall.Open(".", syscall.O_RDONLY, 0)
+ if err != nil {
+ return err
}
- path, err := dirfdAbs(dirfd, path)
+ defer syscall.Close(cwd)
+ err = syscall.Fchdir(dirfd)
if err != nil {
return err
}
- return syscall.Unlink(path)
+ defer syscall.Fchdir(cwd)
+ if (flags & unix.AT_REMOVEDIR) != 0 {
+ return syscall.Rmdir(path)
+ } else {
+ return syscall.Unlink(path)
+ }
}
// Poor man's Mknodat
diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go
index 277015e..0e9d6ac 100644
--- a/internal/syscallcompat/sys_linux.go
+++ b/internal/syscallcompat/sys_linux.go
@@ -54,9 +54,19 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e
return syscall.Renameat(olddirfd, oldpath, newdirfd, newpath)
}
-// Unlinkat wraps the Unlinkat syscall.
-func Unlinkat(dirfd int, path string) error {
- return syscall.Unlinkat(dirfd, path)
+// Unlinkat syscall. In old versions the 'flags' argument was missing, so
+// manually call it by using the corresponding syscall number.
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = syscall.BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall.Syscall(syscall.SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = e1
+ }
+ return
}
// Mknodat wraps the Mknodat syscall.