aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/sys/unix/xattr_bsd.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/sys/unix/xattr_bsd.go')
-rw-r--r--vendor/golang.org/x/sys/unix/xattr_bsd.go281
1 files changed, 281 insertions, 0 deletions
diff --git a/vendor/golang.org/x/sys/unix/xattr_bsd.go b/vendor/golang.org/x/sys/unix/xattr_bsd.go
new file mode 100644
index 0000000..f5f8e9f
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/xattr_bsd.go
@@ -0,0 +1,281 @@
1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build freebsd || netbsd
6// +build freebsd netbsd
7
8package unix
9
10import (
11 "strings"
12 "unsafe"
13)
14
15// Derive extattr namespace and attribute name
16
17func 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
36func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) {
37 if len(dest) > idx {
38 return unsafe.Pointer(&dest[idx])
39 }
40 if dest != nil {
41 // extattr_get_file and extattr_list_file treat NULL differently from
42 // a non-NULL pointer of length zero. Preserve the property of nilness,
43 // even if we can't use dest directly.
44 return unsafe.Pointer(&_zero)
45 }
46 return nil
47}
48
49// FreeBSD and NetBSD implement their own syscalls to handle extended attributes
50
51func Getxattr(file string, attr string, dest []byte) (sz int, err error) {
52 d := initxattrdest(dest, 0)
53 destsize := len(dest)
54
55 nsid, a, err := xattrnamespace(attr)
56 if err != nil {
57 return -1, err
58 }
59
60 return ExtattrGetFile(file, nsid, a, uintptr(d), destsize)
61}
62
63func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
64 d := initxattrdest(dest, 0)
65 destsize := len(dest)
66
67 nsid, a, err := xattrnamespace(attr)
68 if err != nil {
69 return -1, err
70 }
71
72 return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize)
73}
74
75func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
76 d := initxattrdest(dest, 0)
77 destsize := len(dest)
78
79 nsid, a, err := xattrnamespace(attr)
80 if err != nil {
81 return -1, err
82 }
83
84 return ExtattrGetLink(link, nsid, a, uintptr(d), destsize)
85}
86
87// flags are unused on FreeBSD
88
89func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
90 var d unsafe.Pointer
91 if len(data) > 0 {
92 d = unsafe.Pointer(&data[0])
93 }
94 datasiz := len(data)
95
96 nsid, a, err := xattrnamespace(attr)
97 if err != nil {
98 return
99 }
100
101 _, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz)
102 return
103}
104
105func Setxattr(file string, attr string, data []byte, flags int) (err error) {
106 var d unsafe.Pointer
107 if len(data) > 0 {
108 d = unsafe.Pointer(&data[0])
109 }
110 datasiz := len(data)
111
112 nsid, a, err := xattrnamespace(attr)
113 if err != nil {
114 return
115 }
116
117 _, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz)
118 return
119}
120
121func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
122 var d unsafe.Pointer
123 if len(data) > 0 {
124 d = unsafe.Pointer(&data[0])
125 }
126 datasiz := len(data)
127
128 nsid, a, err := xattrnamespace(attr)
129 if err != nil {
130 return
131 }
132
133 _, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz)
134 return
135}
136
137func Removexattr(file string, attr string) (err error) {
138 nsid, a, err := xattrnamespace(attr)
139 if err != nil {
140 return
141 }
142
143 err = ExtattrDeleteFile(file, nsid, a)
144 return
145}
146
147func Fremovexattr(fd int, attr string) (err error) {
148 nsid, a, err := xattrnamespace(attr)
149 if err != nil {
150 return
151 }
152
153 err = ExtattrDeleteFd(fd, nsid, a)
154 return
155}
156
157func Lremovexattr(link string, attr string) (err error) {
158 nsid, a, err := xattrnamespace(attr)
159 if err != nil {
160 return
161 }
162
163 err = ExtattrDeleteLink(link, nsid, a)
164 return
165}
166
167func Listxattr(file string, dest []byte) (sz int, err error) {
168 destsiz := len(dest)
169
170 // FreeBSD won't allow you to list xattrs from multiple namespaces
171 s, pos := 0, 0
172 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
173 stmp, e := ListxattrNS(file, nsid, dest[pos:])
174
175 /* Errors accessing system attrs are ignored so that
176 * we can implement the Linux-like behavior of omitting errors that
177 * we don't have read permissions on
178 *
179 * Linux will still error if we ask for user attributes on a file that
180 * we don't have read permissions on, so don't ignore those errors
181 */
182 if e != nil {
183 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
184 continue
185 }
186 return s, e
187 }
188
189 s += stmp
190 pos = s
191 if pos > destsiz {
192 pos = destsiz
193 }
194 }
195
196 return s, nil
197}
198
199func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
200 d := initxattrdest(dest, 0)
201 destsiz := len(dest)
202
203 s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
204 if e != nil {
205 return 0, err
206 }
207
208 return s, nil
209}
210
211func Flistxattr(fd int, dest []byte) (sz int, err error) {
212 destsiz := len(dest)
213
214 s, pos := 0, 0
215 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
216 stmp, e := FlistxattrNS(fd, nsid, dest[pos:])
217
218 if e != nil {
219 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
220 continue
221 }
222 return s, e
223 }
224
225 s += stmp
226 pos = s
227 if pos > destsiz {
228 pos = destsiz
229 }
230 }
231
232 return s, nil
233}
234
235func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
236 d := initxattrdest(dest, 0)
237 destsiz := len(dest)
238
239 s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
240 if e != nil {
241 return 0, err
242 }
243
244 return s, nil
245}
246
247func Llistxattr(link string, dest []byte) (sz int, err error) {
248 destsiz := len(dest)
249
250 s, pos := 0, 0
251 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
252 stmp, e := LlistxattrNS(link, nsid, dest[pos:])
253
254 if e != nil {
255 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
256 continue
257 }
258 return s, e
259 }
260
261 s += stmp
262 pos = s
263 if pos > destsiz {
264 pos = destsiz
265 }
266 }
267
268 return s, nil
269}
270
271func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) {
272 d := initxattrdest(dest, 0)
273 destsiz := len(dest)
274
275 s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
276 if e != nil {
277 return 0, err
278 }
279
280 return s, nil
281}