cubefs

Форк
0
/x
/
xattr_bsd.go 
281 строка · 5.7 Кб
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

8
package unix
9

10
import (
11
	"strings"
12
	"unsafe"
13
)
14

15
// Derive extattr namespace and attribute name
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
	}
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

51
func 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

63
func 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

75
func 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

89
func 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

105
func 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

121
func 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

137
func 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

147
func 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

157
func 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

167
func 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

199
func 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

211
func 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

235
func 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

247
func 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

271
func 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
}
282

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.