Skip to content

Commit 05b05ed

Browse files
authored
F* functions don't work for some files on macOS. (#76)
1 parent 1990dd4 commit 05b05ed

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

xattr_darwin.go

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package xattr
66
import (
77
"os"
88
"syscall"
9+
"unsafe"
910

1011
"golang.org/x/sys/unix"
1112
)
@@ -37,7 +38,11 @@ func lgetxattr(path string, name string, data []byte) (int, error) {
3738
}
3839

3940
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
40-
return getxattr(f.Name(), name, data)
41+
path, err := getPath(f)
42+
if err != nil {
43+
return 0, err
44+
}
45+
return getxattr(path, name, data)
4146
}
4247

4348
func setxattr(path string, name string, data []byte, flags int) error {
@@ -49,7 +54,11 @@ func lsetxattr(path string, name string, data []byte, flags int) error {
4954
}
5055

5156
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
52-
return setxattr(f.Name(), name, data, flags)
57+
path, err := getPath(f)
58+
if err != nil {
59+
return err
60+
}
61+
return setxattr(path, name, data, flags)
5362
}
5463

5564
func removexattr(path string, name string) error {
@@ -61,7 +70,11 @@ func lremovexattr(path string, name string) error {
6170
}
6271

6372
func fremovexattr(f *os.File, name string) error {
64-
return removexattr(f.Name(), name)
73+
path, err := getPath(f)
74+
if err != nil {
75+
return err
76+
}
77+
return removexattr(path, name)
6578
}
6679

6780
func listxattr(path string, data []byte) (int, error) {
@@ -73,7 +86,28 @@ func llistxattr(path string, data []byte) (int, error) {
7386
}
7487

7588
func flistxattr(f *os.File, data []byte) (int, error) {
76-
return listxattr(f.Name(), data)
89+
path, err := getPath(f)
90+
if err != nil {
91+
return 0, err
92+
}
93+
return listxattr(path, data)
94+
}
95+
96+
// getPath returns the full path to the specified file.
97+
func getPath(f *os.File) (string, error) {
98+
var buf [unix.PathMax]byte
99+
_, _, err := unix.Syscall(unix.SYS_FCNTL,
100+
uintptr(int(f.Fd())),
101+
uintptr(unix.F_GETPATH),
102+
uintptr(unsafe.Pointer(&buf[0])))
103+
if err != 0 {
104+
return "", err
105+
}
106+
n := 0
107+
for n < len(buf) && buf[n] != 0 {
108+
n++
109+
}
110+
return string(buf[:n]), nil
77111
}
78112

79113
// stringsFromByteSlice converts a sequence of attributes to a []string.

0 commit comments

Comments
 (0)