forked from ebhomengo/niki
1
0
Fork 0
niki/vendor/golang.org/x/sys/unix/xattr_bsd.go

441 lines
5.8 KiB
Go
Raw Normal View History

2024-02-18 10:42:21 +00:00
// Copyright 2018 The Go Authors. All rights reserved.
2024-02-18 10:42:21 +00:00
// Use of this source code is governed by a BSD-style
2024-02-18 10:42:21 +00:00
// license that can be found in the LICENSE file.
//go:build freebsd || netbsd
package unix
import (
"strings"
"unsafe"
)
// Derive extattr namespace and attribute name
func xattrnamespace(fullattr string) (ns int, attr string, err error) {
2024-02-18 10:42:21 +00:00
s := strings.IndexByte(fullattr, '.')
2024-02-18 10:42:21 +00:00
if s == -1 {
2024-02-18 10:42:21 +00:00
return -1, "", ENOATTR
2024-02-18 10:42:21 +00:00
}
namespace := fullattr[0:s]
2024-02-18 10:42:21 +00:00
attr = fullattr[s+1:]
switch namespace {
2024-02-18 10:42:21 +00:00
case "user":
2024-02-18 10:42:21 +00:00
return EXTATTR_NAMESPACE_USER, attr, nil
2024-02-18 10:42:21 +00:00
case "system":
2024-02-18 10:42:21 +00:00
return EXTATTR_NAMESPACE_SYSTEM, attr, nil
2024-02-18 10:42:21 +00:00
default:
2024-02-18 10:42:21 +00:00
return -1, "", ENOATTR
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) {
2024-02-18 10:42:21 +00:00
if len(dest) > idx {
2024-02-18 10:42:21 +00:00
return unsafe.Pointer(&dest[idx])
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if dest != nil {
2024-02-18 10:42:21 +00:00
// extattr_get_file and extattr_list_file treat NULL differently from
2024-02-18 10:42:21 +00:00
// a non-NULL pointer of length zero. Preserve the property of nilness,
2024-02-18 10:42:21 +00:00
// even if we can't use dest directly.
2024-02-18 10:42:21 +00:00
return unsafe.Pointer(&_zero)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
// FreeBSD and NetBSD implement their own syscalls to handle extended attributes
func Getxattr(file string, attr string, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
d := initxattrdest(dest, 0)
2024-02-18 10:42:21 +00:00
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return -1, err
2024-02-18 10:42:21 +00:00
}
return ExtattrGetFile(file, nsid, a, uintptr(d), destsize)
2024-02-18 10:42:21 +00:00
}
func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
d := initxattrdest(dest, 0)
2024-02-18 10:42:21 +00:00
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return -1, err
2024-02-18 10:42:21 +00:00
}
return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize)
2024-02-18 10:42:21 +00:00
}
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
d := initxattrdest(dest, 0)
2024-02-18 10:42:21 +00:00
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return -1, err
2024-02-18 10:42:21 +00:00
}
return ExtattrGetLink(link, nsid, a, uintptr(d), destsize)
2024-02-18 10:42:21 +00:00
}
// flags are unused on FreeBSD
func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
2024-02-18 10:42:21 +00:00
var d unsafe.Pointer
2024-02-18 10:42:21 +00:00
if len(data) > 0 {
2024-02-18 10:42:21 +00:00
d = unsafe.Pointer(&data[0])
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
_, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz)
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
func Setxattr(file string, attr string, data []byte, flags int) (err error) {
2024-02-18 10:42:21 +00:00
var d unsafe.Pointer
2024-02-18 10:42:21 +00:00
if len(data) > 0 {
2024-02-18 10:42:21 +00:00
d = unsafe.Pointer(&data[0])
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
_, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz)
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
2024-02-18 10:42:21 +00:00
var d unsafe.Pointer
2024-02-18 10:42:21 +00:00
if len(data) > 0 {
2024-02-18 10:42:21 +00:00
d = unsafe.Pointer(&data[0])
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
_, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz)
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
func Removexattr(file string, attr string) (err error) {
2024-02-18 10:42:21 +00:00
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
err = ExtattrDeleteFile(file, nsid, a)
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
func Fremovexattr(fd int, attr string) (err error) {
2024-02-18 10:42:21 +00:00
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
err = ExtattrDeleteFd(fd, nsid, a)
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
func Lremovexattr(link string, attr string) (err error) {
2024-02-18 10:42:21 +00:00
nsid, a, err := xattrnamespace(attr)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
err = ExtattrDeleteLink(link, nsid, a)
2024-02-18 10:42:21 +00:00
return
2024-02-18 10:42:21 +00:00
}
func Listxattr(file string, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
destsiz := len(dest)
// FreeBSD won't allow you to list xattrs from multiple namespaces
2024-02-18 10:42:21 +00:00
s, pos := 0, 0
2024-02-18 10:42:21 +00:00
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
2024-02-18 10:42:21 +00:00
stmp, e := ListxattrNS(file, nsid, dest[pos:])
/* Errors accessing system attrs are ignored so that
2024-02-18 10:42:21 +00:00
* we can implement the Linux-like behavior of omitting errors that
2024-02-18 10:42:21 +00:00
* we don't have read permissions on
2024-02-18 10:42:21 +00:00
*
2024-02-18 10:42:21 +00:00
* Linux will still error if we ask for user attributes on a file that
2024-02-18 10:42:21 +00:00
* we don't have read permissions on, so don't ignore those errors
2024-02-18 10:42:21 +00:00
*/
2024-02-18 10:42:21 +00:00
if e != nil {
2024-02-18 10:42:21 +00:00
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
2024-02-18 10:42:21 +00:00
continue
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return s, e
2024-02-18 10:42:21 +00:00
}
s += stmp
2024-02-18 10:42:21 +00:00
pos = s
2024-02-18 10:42:21 +00:00
if pos > destsiz {
2024-02-18 10:42:21 +00:00
pos = destsiz
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
return s, nil
2024-02-18 10:42:21 +00:00
}
func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
d := initxattrdest(dest, 0)
2024-02-18 10:42:21 +00:00
destsiz := len(dest)
s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
2024-02-18 10:42:21 +00:00
if e != nil {
2024-02-18 10:42:21 +00:00
return 0, err
2024-02-18 10:42:21 +00:00
}
return s, nil
2024-02-18 10:42:21 +00:00
}
func Flistxattr(fd int, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
destsiz := len(dest)
s, pos := 0, 0
2024-02-18 10:42:21 +00:00
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
2024-02-18 10:42:21 +00:00
stmp, e := FlistxattrNS(fd, nsid, dest[pos:])
if e != nil {
2024-02-18 10:42:21 +00:00
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
2024-02-18 10:42:21 +00:00
continue
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return s, e
2024-02-18 10:42:21 +00:00
}
s += stmp
2024-02-18 10:42:21 +00:00
pos = s
2024-02-18 10:42:21 +00:00
if pos > destsiz {
2024-02-18 10:42:21 +00:00
pos = destsiz
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
return s, nil
2024-02-18 10:42:21 +00:00
}
func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
d := initxattrdest(dest, 0)
2024-02-18 10:42:21 +00:00
destsiz := len(dest)
s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
2024-02-18 10:42:21 +00:00
if e != nil {
2024-02-18 10:42:21 +00:00
return 0, err
2024-02-18 10:42:21 +00:00
}
return s, nil
2024-02-18 10:42:21 +00:00
}
func Llistxattr(link string, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
destsiz := len(dest)
s, pos := 0, 0
2024-02-18 10:42:21 +00:00
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
2024-02-18 10:42:21 +00:00
stmp, e := LlistxattrNS(link, nsid, dest[pos:])
if e != nil {
2024-02-18 10:42:21 +00:00
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
2024-02-18 10:42:21 +00:00
continue
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return s, e
2024-02-18 10:42:21 +00:00
}
s += stmp
2024-02-18 10:42:21 +00:00
pos = s
2024-02-18 10:42:21 +00:00
if pos > destsiz {
2024-02-18 10:42:21 +00:00
pos = destsiz
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
return s, nil
2024-02-18 10:42:21 +00:00
}
func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) {
2024-02-18 10:42:21 +00:00
d := initxattrdest(dest, 0)
2024-02-18 10:42:21 +00:00
destsiz := len(dest)
s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
2024-02-18 10:42:21 +00:00
if e != nil {
2024-02-18 10:42:21 +00:00
return 0, err
2024-02-18 10:42:21 +00:00
}
return s, nil
2024-02-18 10:42:21 +00:00
}