1
2
3
4
19
20 package sysx
21
22 import (
23 "bytes"
24
25 "golang.org/x/sys/unix"
26 )
27
28
29
30 func Listxattr(path string) ([]string, error) {
31 return listxattrAll(path, unix.Listxattr)
32 }
33
34
35 func Removexattr(path string, attr string) (err error) {
36 return unix.Removexattr(path, attr)
37 }
38
39
40 func Setxattr(path string, attr string, data []byte, flags int) (err error) {
41 return unix.Setxattr(path, attr, data, flags)
42 }
43
44
45 func Getxattr(path, attr string) ([]byte, error) {
46 return getxattrAll(path, attr, unix.Getxattr)
47 }
48
49
50 func LListxattr(path string) ([]string, error) {
51 return listxattrAll(path, unix.Llistxattr)
52 }
53
54
55 func LRemovexattr(path string, attr string) (err error) {
56 return unix.Lremovexattr(path, attr)
57 }
58
59
60 func LSetxattr(path string, attr string, data []byte, flags int) (err error) {
61 return unix.Lsetxattr(path, attr, data, flags)
62 }
63
64
65 func LGetxattr(path, attr string) ([]byte, error) {
66 return getxattrAll(path, attr, unix.Lgetxattr)
67 }
68
69 const defaultXattrBufferSize = 128
70
71 type listxattrFunc func(path string, dest []byte) (int, error)
72
73 func listxattrAll(path string, listFunc listxattrFunc) ([]string, error) {
74 buf := make([]byte, defaultXattrBufferSize)
75 n, err := listFunc(path, buf)
76 for err == unix.ERANGE {
77
78 n, err = listFunc(path, []byte{})
79 if err != nil {
80 return nil, err
81 }
82 buf = make([]byte, n)
83 n, err = listFunc(path, buf)
84 }
85 if err != nil {
86 return nil, err
87 }
88
89 ps := bytes.Split(bytes.TrimSuffix(buf[:n], []byte{0}), []byte{0})
90 var entries []string
91 for _, p := range ps {
92 if len(p) > 0 {
93 entries = append(entries, string(p))
94 }
95 }
96
97 return entries, nil
98 }
99
100 type getxattrFunc func(string, string, []byte) (int, error)
101
102 func getxattrAll(path, attr string, getFunc getxattrFunc) ([]byte, error) {
103 buf := make([]byte, defaultXattrBufferSize)
104 n, err := getFunc(path, attr, buf)
105 for err == unix.ERANGE {
106
107 n, err = getFunc(path, attr, []byte{})
108 if err != nil {
109 return nil, err
110 }
111 buf = make([]byte, n)
112 n, err = getFunc(path, attr, buf)
113 }
114 if err != nil {
115 return nil, err
116 }
117 return buf[:n], nil
118 }
119
View as plain text