Skip to content

Commit 63ea559

Browse files
dmgkgopherbot
authored andcommitted
unix: add namespaced versions of Listxattr/Flistxattr/Llistxattr on *BSD
Current extended attributes API mixes together attributes from different namespaces without a way to separate them. Add versions of *listxattr functions that return attributes only from the specified namespace. For golang/go#54357 Change-Id: I605d677dd2f2a17541bc02f3146a7509c69269c9 Reviewed-on: https://go-review.googlesource.com/c/sys/+/430215 Reviewed-by: Yuval Pavel Zholkover <paulzhol@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Dmitri Goutnik <dgoutnik@gmail.com> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Jenny Rakoczy <jenny@golang.org> Reviewed-by: Jenny Rakoczy <jenny@golang.org>
1 parent 76c7481 commit 63ea559

File tree

1 file changed

+65
-30
lines changed

1 file changed

+65
-30
lines changed

unix/xattr_bsd.go

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,12 @@ func Lremovexattr(link string, attr string) (err error) {
160160
}
161161

162162
func Listxattr(file string, dest []byte) (sz int, err error) {
163-
d := initxattrdest(dest, 0)
164163
destsiz := len(dest)
165164

166165
// FreeBSD won't allow you to list xattrs from multiple namespaces
167-
s := 0
166+
s, pos := 0, 0
168167
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:])
170169

171170
/* Errors accessing system attrs are ignored so that
172171
* we can implement the Linux-like behavior of omitting errors that
@@ -175,66 +174,102 @@ func Listxattr(file string, dest []byte) (sz int, err error) {
175174
* Linux will still error if we ask for user attributes on a file that
176175
* we don't have read permissions on, so don't ignore those errors
177176
*/
178-
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
179-
continue
180-
} else if e != nil {
177+
if e != nil {
178+
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
179+
continue
180+
}
181181
return s, e
182182
}
183183

184184
s += stmp
185-
destsiz -= s
186-
if destsiz < 0 {
187-
destsiz = 0
185+
pos = s
186+
if pos > destsiz {
187+
pos = destsiz
188188
}
189-
d = initxattrdest(dest, s)
190189
}
191190

192191
return s, nil
193192
}
194193

195-
func Flistxattr(fd int, dest []byte) (sz int, err error) {
194+
func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
196195
d := initxattrdest(dest, 0)
197196
destsiz := len(dest)
198197

199-
s := 0
198+
s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
199+
if e != nil {
200+
return 0, err
201+
}
202+
203+
return s, nil
204+
}
205+
206+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
207+
destsiz := len(dest)
208+
209+
s, pos := 0, 0
200210
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
201-
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
202-
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
203-
continue
204-
} else if e != nil {
211+
stmp, e := FlistxattrNS(fd, nsid, dest[pos:])
212+
213+
if e != nil {
214+
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
215+
continue
216+
}
205217
return s, e
206218
}
207219

208220
s += stmp
209-
destsiz -= s
210-
if destsiz < 0 {
211-
destsiz = 0
221+
pos = s
222+
if pos > destsiz {
223+
pos = destsiz
212224
}
213-
d = initxattrdest(dest, s)
214225
}
215226

216227
return s, nil
217228
}
218229

219-
func Llistxattr(link string, dest []byte) (sz int, err error) {
230+
func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
220231
d := initxattrdest(dest, 0)
221232
destsiz := len(dest)
222233

223-
s := 0
234+
s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
235+
if e != nil {
236+
return 0, err
237+
}
238+
239+
return s, nil
240+
}
241+
242+
func Llistxattr(link string, dest []byte) (sz int, err error) {
243+
destsiz := len(dest)
244+
245+
s, pos := 0, 0
224246
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
225-
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
226-
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
227-
continue
228-
} else if e != nil {
247+
stmp, e := LlistxattrNS(link, nsid, dest[pos:])
248+
249+
if e != nil {
250+
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
251+
continue
252+
}
229253
return s, e
230254
}
231255

232256
s += stmp
233-
destsiz -= s
234-
if destsiz < 0 {
235-
destsiz = 0
257+
pos = s
258+
if pos > destsiz {
259+
pos = destsiz
236260
}
237-
d = initxattrdest(dest, s)
261+
}
262+
263+
return s, nil
264+
}
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
238273
}
239274

240275
return s, nil

0 commit comments

Comments
 (0)