1
2
3
4
5
6
7
8 package unix
9
10 import (
11 "strings"
12 "unsafe"
13 )
14
15
16
17 func xattrnamespace(fullattr string) (ns int, attr string, err error) {
18 s := strings.IndexByte(fullattr, '.')
19 if s == -1 {
20 return -1, "", ENOATTR
21 }
22
23 namespace := fullattr[0:s]
24 attr = fullattr[s+1:]
25
26 switch namespace {
27 case "user":
28 return EXTATTR_NAMESPACE_USER, attr, nil
29 case "system":
30 return EXTATTR_NAMESPACE_SYSTEM, attr, nil
31 default:
32 return -1, "", ENOATTR
33 }
34 }
35
36 func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) {
37 if len(dest) > idx {
38 return unsafe.Pointer(&dest[idx])
39 } else {
40 return unsafe.Pointer(_zero)
41 }
42 }
43
44
45
46 func Getxattr(file string, attr string, dest []byte) (sz int, err error) {
47 d := initxattrdest(dest, 0)
48 destsize := len(dest)
49
50 nsid, a, err := xattrnamespace(attr)
51 if err != nil {
52 return -1, err
53 }
54
55 return ExtattrGetFile(file, nsid, a, uintptr(d), destsize)
56 }
57
58 func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
59 d := initxattrdest(dest, 0)
60 destsize := len(dest)
61
62 nsid, a, err := xattrnamespace(attr)
63 if err != nil {
64 return -1, err
65 }
66
67 return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize)
68 }
69
70 func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
71 d := initxattrdest(dest, 0)
72 destsize := len(dest)
73
74 nsid, a, err := xattrnamespace(attr)
75 if err != nil {
76 return -1, err
77 }
78
79 return ExtattrGetLink(link, nsid, a, uintptr(d), destsize)
80 }
81
82
83
84 func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
85 var d unsafe.Pointer
86 if len(data) > 0 {
87 d = unsafe.Pointer(&data[0])
88 }
89 datasiz := len(data)
90
91 nsid, a, err := xattrnamespace(attr)
92 if err != nil {
93 return
94 }
95
96 _, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz)
97 return
98 }
99
100 func Setxattr(file string, attr string, data []byte, flags int) (err error) {
101 var d unsafe.Pointer
102 if len(data) > 0 {
103 d = unsafe.Pointer(&data[0])
104 }
105 datasiz := len(data)
106
107 nsid, a, err := xattrnamespace(attr)
108 if err != nil {
109 return
110 }
111
112 _, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz)
113 return
114 }
115
116 func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
117 var d unsafe.Pointer
118 if len(data) > 0 {
119 d = unsafe.Pointer(&data[0])
120 }
121 datasiz := len(data)
122
123 nsid, a, err := xattrnamespace(attr)
124 if err != nil {
125 return
126 }
127
128 _, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz)
129 return
130 }
131
132 func Removexattr(file string, attr string) (err error) {
133 nsid, a, err := xattrnamespace(attr)
134 if err != nil {
135 return
136 }
137
138 err = ExtattrDeleteFile(file, nsid, a)
139 return
140 }
141
142 func Fremovexattr(fd int, attr string) (err error) {
143 nsid, a, err := xattrnamespace(attr)
144 if err != nil {
145 return
146 }
147
148 err = ExtattrDeleteFd(fd, nsid, a)
149 return
150 }
151
152 func Lremovexattr(link string, attr string) (err error) {
153 nsid, a, err := xattrnamespace(attr)
154 if err != nil {
155 return
156 }
157
158 err = ExtattrDeleteLink(link, nsid, a)
159 return
160 }
161
162 func Listxattr(file string, dest []byte) (sz int, err error) {
163 d := initxattrdest(dest, 0)
164 destsiz := len(dest)
165
166
167 s := 0
168 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
169 stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
170
171
178 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
179 continue
180 } else if e != nil {
181 return s, e
182 }
183
184 s += stmp
185 destsiz -= s
186 if destsiz < 0 {
187 destsiz = 0
188 }
189 d = initxattrdest(dest, s)
190 }
191
192 return s, nil
193 }
194
195 func Flistxattr(fd int, dest []byte) (sz int, err error) {
196 d := initxattrdest(dest, 0)
197 destsiz := len(dest)
198
199 s := 0
200 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
201 stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
202 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
203 continue
204 } else if e != nil {
205 return s, e
206 }
207
208 s += stmp
209 destsiz -= s
210 if destsiz < 0 {
211 destsiz = 0
212 }
213 d = initxattrdest(dest, s)
214 }
215
216 return s, nil
217 }
218
219 func Llistxattr(link string, dest []byte) (sz int, err error) {
220 d := initxattrdest(dest, 0)
221 destsiz := len(dest)
222
223 s := 0
224 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
225 stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
226 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
227 continue
228 } else if e != nil {
229 return s, e
230 }
231
232 s += stmp
233 destsiz -= s
234 if destsiz < 0 {
235 destsiz = 0
236 }
237 d = initxattrdest(dest, s)
238 }
239
240 return s, nil
241 }
242
View as plain text