.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / sys@v0.0.0-20210124154548-22da62e12c0c / unix / xattr_bsd.go
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 // +build freebsd netbsd
6
7 package unix
8
9 import (
10         "strings"
11         "unsafe"
12 )
13
14 // Derive extattr namespace and attribute name
15
16 func xattrnamespace(fullattr string) (ns int, attr string, err error) {
17         s := strings.IndexByte(fullattr, '.')
18         if s == -1 {
19                 return -1, "", ENOATTR
20         }
21
22         namespace := fullattr[0:s]
23         attr = fullattr[s+1:]
24
25         switch namespace {
26         case "user":
27                 return EXTATTR_NAMESPACE_USER, attr, nil
28         case "system":
29                 return EXTATTR_NAMESPACE_SYSTEM, attr, nil
30         default:
31                 return -1, "", ENOATTR
32         }
33 }
34
35 func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) {
36         if len(dest) > idx {
37                 return unsafe.Pointer(&dest[idx])
38         } else {
39                 return unsafe.Pointer(_zero)
40         }
41 }
42
43 // FreeBSD and NetBSD implement their own syscalls to handle extended attributes
44
45 func Getxattr(file string, attr string, dest []byte) (sz int, err error) {
46         d := initxattrdest(dest, 0)
47         destsize := len(dest)
48
49         nsid, a, err := xattrnamespace(attr)
50         if err != nil {
51                 return -1, err
52         }
53
54         return ExtattrGetFile(file, nsid, a, uintptr(d), destsize)
55 }
56
57 func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
58         d := initxattrdest(dest, 0)
59         destsize := len(dest)
60
61         nsid, a, err := xattrnamespace(attr)
62         if err != nil {
63                 return -1, err
64         }
65
66         return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize)
67 }
68
69 func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
70         d := initxattrdest(dest, 0)
71         destsize := len(dest)
72
73         nsid, a, err := xattrnamespace(attr)
74         if err != nil {
75                 return -1, err
76         }
77
78         return ExtattrGetLink(link, nsid, a, uintptr(d), destsize)
79 }
80
81 // flags are unused on FreeBSD
82
83 func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
84         var d unsafe.Pointer
85         if len(data) > 0 {
86                 d = unsafe.Pointer(&data[0])
87         }
88         datasiz := len(data)
89
90         nsid, a, err := xattrnamespace(attr)
91         if err != nil {
92                 return
93         }
94
95         _, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz)
96         return
97 }
98
99 func Setxattr(file string, attr string, data []byte, flags int) (err error) {
100         var d unsafe.Pointer
101         if len(data) > 0 {
102                 d = unsafe.Pointer(&data[0])
103         }
104         datasiz := len(data)
105
106         nsid, a, err := xattrnamespace(attr)
107         if err != nil {
108                 return
109         }
110
111         _, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz)
112         return
113 }
114
115 func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
116         var d unsafe.Pointer
117         if len(data) > 0 {
118                 d = unsafe.Pointer(&data[0])
119         }
120         datasiz := len(data)
121
122         nsid, a, err := xattrnamespace(attr)
123         if err != nil {
124                 return
125         }
126
127         _, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz)
128         return
129 }
130
131 func Removexattr(file string, attr string) (err error) {
132         nsid, a, err := xattrnamespace(attr)
133         if err != nil {
134                 return
135         }
136
137         err = ExtattrDeleteFile(file, nsid, a)
138         return
139 }
140
141 func Fremovexattr(fd int, attr string) (err error) {
142         nsid, a, err := xattrnamespace(attr)
143         if err != nil {
144                 return
145         }
146
147         err = ExtattrDeleteFd(fd, nsid, a)
148         return
149 }
150
151 func Lremovexattr(link string, attr string) (err error) {
152         nsid, a, err := xattrnamespace(attr)
153         if err != nil {
154                 return
155         }
156
157         err = ExtattrDeleteLink(link, nsid, a)
158         return
159 }
160
161 func Listxattr(file string, dest []byte) (sz int, err error) {
162         d := initxattrdest(dest, 0)
163         destsiz := len(dest)
164
165         // FreeBSD won't allow you to list xattrs from multiple namespaces
166         s := 0
167         for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
168                 stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
169
170                 /* Errors accessing system attrs are ignored so that
171                  * we can implement the Linux-like behavior of omitting errors that
172                  * we don't have read permissions on
173                  *
174                  * Linux will still error if we ask for user attributes on a file that
175                  * we don't have read permissions on, so don't ignore those errors
176                  */
177                 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
178                         continue
179                 } else if e != nil {
180                         return s, e
181                 }
182
183                 s += stmp
184                 destsiz -= s
185                 if destsiz < 0 {
186                         destsiz = 0
187                 }
188                 d = initxattrdest(dest, s)
189         }
190
191         return s, nil
192 }
193
194 func Flistxattr(fd int, dest []byte) (sz int, err error) {
195         d := initxattrdest(dest, 0)
196         destsiz := len(dest)
197
198         s := 0
199         for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
200                 stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
201                 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
202                         continue
203                 } else if e != nil {
204                         return s, e
205                 }
206
207                 s += stmp
208                 destsiz -= s
209                 if destsiz < 0 {
210                         destsiz = 0
211                 }
212                 d = initxattrdest(dest, s)
213         }
214
215         return s, nil
216 }
217
218 func Llistxattr(link string, dest []byte) (sz int, err error) {
219         d := initxattrdest(dest, 0)
220         destsiz := len(dest)
221
222         s := 0
223         for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
224                 stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
225                 if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
226                         continue
227                 } else if e != nil {
228                         return s, e
229                 }
230
231                 s += stmp
232                 destsiz -= s
233                 if destsiz < 0 {
234                         destsiz = 0
235                 }
236                 d = initxattrdest(dest, s)
237         }
238
239         return s, nil
240 }