158 err = ExtattrDeleteLink(link, nsid, a) |
158 err = ExtattrDeleteLink(link, nsid, a) |
159 return |
159 return |
160 } |
160 } |
161 |
161 |
162 func Listxattr(file string, dest []byte) (sz int, err error) { |
162 func Listxattr(file string, dest []byte) (sz int, err error) { |
163 d := initxattrdest(dest, 0) |
|
164 destsiz := len(dest) |
163 destsiz := len(dest) |
165 |
164 |
166 // FreeBSD won't allow you to list xattrs from multiple namespaces |
165 // FreeBSD won't allow you to list xattrs from multiple namespaces |
167 s := 0 |
166 s, pos := 0, 0 |
168 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
167 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
169 stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) |
168 stmp, e := ListxattrNS(file, nsid, dest[pos:]) |
170 |
169 |
171 /* Errors accessing system attrs are ignored so that |
170 /* Errors accessing system attrs are ignored so that |
172 * we can implement the Linux-like behavior of omitting errors that |
171 * we can implement the Linux-like behavior of omitting errors that |
173 * we don't have read permissions on |
172 * we don't have read permissions on |
174 * |
173 * |
175 * Linux will still error if we ask for user attributes on a file that |
174 * Linux will still error if we ask for user attributes on a file that |
176 * we don't have read permissions on, so don't ignore those errors |
175 * we don't have read permissions on, so don't ignore those errors |
177 */ |
176 */ |
178 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
177 if e != nil { |
179 continue |
178 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
180 } else if e != nil { |
179 continue |
|
180 } |
181 return s, e |
181 return s, e |
182 } |
182 } |
183 |
183 |
184 s += stmp |
184 s += stmp |
185 destsiz -= s |
185 pos = s |
186 if destsiz < 0 { |
186 if pos > destsiz { |
187 destsiz = 0 |
187 pos = destsiz |
188 } |
188 } |
189 d = initxattrdest(dest, s) |
189 } |
|
190 |
|
191 return s, nil |
|
192 } |
|
193 |
|
194 func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) { |
|
195 d := initxattrdest(dest, 0) |
|
196 destsiz := len(dest) |
|
197 |
|
198 s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) |
|
199 if e != nil { |
|
200 return 0, err |
190 } |
201 } |
191 |
202 |
192 return s, nil |
203 return s, nil |
193 } |
204 } |
194 |
205 |
195 func Flistxattr(fd int, dest []byte) (sz int, err error) { |
206 func Flistxattr(fd int, dest []byte) (sz int, err error) { |
196 d := initxattrdest(dest, 0) |
207 destsiz := len(dest) |
197 destsiz := len(dest) |
208 |
198 |
209 s, pos := 0, 0 |
199 s := 0 |
|
200 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
210 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
201 stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) |
211 stmp, e := FlistxattrNS(fd, nsid, dest[pos:]) |
202 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
212 |
203 continue |
213 if e != nil { |
204 } else if e != nil { |
214 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
|
215 continue |
|
216 } |
205 return s, e |
217 return s, e |
206 } |
218 } |
207 |
219 |
208 s += stmp |
220 s += stmp |
209 destsiz -= s |
221 pos = s |
210 if destsiz < 0 { |
222 if pos > destsiz { |
211 destsiz = 0 |
223 pos = destsiz |
212 } |
224 } |
213 d = initxattrdest(dest, s) |
225 } |
|
226 |
|
227 return s, nil |
|
228 } |
|
229 |
|
230 func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) { |
|
231 d := initxattrdest(dest, 0) |
|
232 destsiz := len(dest) |
|
233 |
|
234 s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) |
|
235 if e != nil { |
|
236 return 0, err |
214 } |
237 } |
215 |
238 |
216 return s, nil |
239 return s, nil |
217 } |
240 } |
218 |
241 |
219 func Llistxattr(link string, dest []byte) (sz int, err error) { |
242 func Llistxattr(link string, dest []byte) (sz int, err error) { |
220 d := initxattrdest(dest, 0) |
243 destsiz := len(dest) |
221 destsiz := len(dest) |
244 |
222 |
245 s, pos := 0, 0 |
223 s := 0 |
|
224 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
246 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
225 stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) |
247 stmp, e := LlistxattrNS(link, nsid, dest[pos:]) |
226 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
248 |
227 continue |
249 if e != nil { |
228 } else if e != nil { |
250 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
|
251 continue |
|
252 } |
229 return s, e |
253 return s, e |
230 } |
254 } |
231 |
255 |
232 s += stmp |
256 s += stmp |
233 destsiz -= s |
257 pos = s |
234 if destsiz < 0 { |
258 if pos > destsiz { |
235 destsiz = 0 |
259 pos = destsiz |
236 } |
260 } |
237 d = initxattrdest(dest, s) |
261 } |
238 } |
262 |
239 |
263 return s, nil |
240 return s, nil |
264 } |
241 } |
265 |
|
266 func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) { |
|
267 d := initxattrdest(dest, 0) |
|
268 destsiz := len(dest) |
|
269 |
|
270 s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) |
|
271 if e != nil { |
|
272 return 0, err |
|
273 } |
|
274 |
|
275 return s, nil |
|
276 } |