all repos

rss-tools @ master

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/golang.org/x/sys/unix/xattr_bsd.go (view raw)

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