@@ -6,6 +6,7 @@ package xattr
66import (
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
3940func 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
4348func 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
5156func 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
5564func removexattr (path string , name string ) error {
@@ -61,7 +70,11 @@ func lremovexattr(path string, name string) error {
6170}
6271
6372func 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
6780func listxattr (path string , data []byte ) (int , error ) {
@@ -73,7 +86,28 @@ func llistxattr(path string, data []byte) (int, error) {
7386}
7487
7588func 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