vendor: vendor fscrypt integration dependencies

Signed-off-by: Marcel Lauhoff <marcel.lauhoff@suse.com>
This commit is contained in:
Marcel Lauhoff
2022-06-23 13:58:36 +02:00
committed by mergify[bot]
parent cfea8d7562
commit f8faffac89
44 changed files with 8910 additions and 1 deletions

26
vendor/github.com/pkg/xattr/.gitignore generated vendored Normal file
View File

@ -0,0 +1,26 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
.DS_Store
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.swp

25
vendor/github.com/pkg/xattr/LICENSE generated vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2012 Dave Cheney. All rights reserved.
Copyright (c) 2014 Kuba Podgórski. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

45
vendor/github.com/pkg/xattr/README.md generated vendored Normal file
View File

@ -0,0 +1,45 @@
[![GoDoc](https://godoc.org/github.com/pkg/xattr?status.svg)](http://godoc.org/github.com/pkg/xattr)
[![Go Report Card](https://goreportcard.com/badge/github.com/pkg/xattr)](https://goreportcard.com/report/github.com/pkg/xattr)
[![Build Status](https://github.com/pkg/xattr/workflows/build/badge.svg)](https://github.com/pkg/xattr/actions?query=workflow%3Abuild)
[![Codecov](https://codecov.io/gh/pkg/xattr/branch/master/graph/badge.svg)](https://codecov.io/gh/pkg/xattr)
xattr
=====
Extended attribute support for Go (linux + darwin + freebsd + netbsd + solaris).
"Extended attributes are name:value pairs associated permanently with files and directories, similar to the environment strings associated with a process. An attribute may be defined or undefined. If it is defined, its value may be empty or non-empty." [See more...](https://en.wikipedia.org/wiki/Extended_file_attributes)
`SetWithFlags` allows to additionally pass system flags to be forwarded to the underlying calls. FreeBSD and NetBSD do not support this and the parameter will be ignored.
The `L` variants of all functions (`LGet/LSet/...`) are identical to `Get/Set/...` except that they
do not reference a symlink that appears at the end of a path. See
[GoDoc](http://godoc.org/github.com/pkg/xattr) for details.
### Example
```go
const path = "/tmp/myfile"
const prefix = "user."
if err := xattr.Set(path, prefix+"test", []byte("test-attr-value")); err != nil {
log.Fatal(err)
}
var list []string
if list, err = xattr.List(path); err != nil {
log.Fatal(err)
}
var data []byte
if data, err = xattr.Get(path, prefix+"test"); err != nil {
log.Fatal(err)
}
if err = xattr.Remove(path, prefix+"test"); err != nil {
log.Fatal(err)
}
// One can also specify the flags parameter to be passed to the OS.
if err := xattr.SetWithFlags(path, prefix+"test", []byte("test-attr-value"), xattr.XATTR_CREATE); err != nil {
log.Fatal(err)
}
```

255
vendor/github.com/pkg/xattr/xattr.go generated vendored Normal file
View File

@ -0,0 +1,255 @@
/*
Package xattr provides support for extended attributes on linux, darwin and freebsd.
Extended attributes are name:value pairs associated permanently with files and directories,
similar to the environment strings associated with a process.
An attribute may be defined or undefined. If it is defined, its value may be empty or non-empty.
More details you can find here: https://en.wikipedia.org/wiki/Extended_file_attributes .
All functions are provided in triples: Get/LGet/FGet, Set/LSet/FSet etc. The "L"
variant will not follow a symlink at the end of the path, and "F" variant accepts
a file descriptor instead of a path.
Example for "L" variant, assuming path is "/symlink1/symlink2", where both components are
symlinks:
Get will follow "symlink1" and "symlink2" and operate on the target of
"symlink2". LGet will follow "symlink1" but operate directly on "symlink2".
*/
package xattr
import (
"os"
"syscall"
)
// Error records an error and the operation, file path and attribute that caused it.
type Error struct {
Op string
Path string
Name string
Err error
}
func (e *Error) Error() (errstr string) {
if e.Op != "" {
errstr += e.Op
}
if e.Path != "" {
if errstr != "" {
errstr += " "
}
errstr += e.Path
}
if e.Name != "" {
if errstr != "" {
errstr += " "
}
errstr += e.Name
}
if e.Err != nil {
if errstr != "" {
errstr += ": "
}
errstr += e.Err.Error()
}
return
}
// Get retrieves extended attribute data associated with path. It will follow
// all symlinks along the path.
func Get(path, name string) ([]byte, error) {
return get(path, name, func(name string, data []byte) (int, error) {
return getxattr(path, name, data)
})
}
// LGet is like Get but does not follow a symlink at the end of the path.
func LGet(path, name string) ([]byte, error) {
return get(path, name, func(name string, data []byte) (int, error) {
return lgetxattr(path, name, data)
})
}
// FGet is like Get but accepts a os.File instead of a file path.
func FGet(f *os.File, name string) ([]byte, error) {
return get(f.Name(), name, func(name string, data []byte) (int, error) {
return fgetxattr(f, name, data)
})
}
type getxattrFunc func(name string, data []byte) (int, error)
// get contains the buffer allocation logic used by both Get and LGet.
func get(path string, name string, getxattrFunc getxattrFunc) ([]byte, error) {
const (
// Start with a 1 KB buffer for the xattr value
initialBufSize = 1024
// The theoretical maximum xattr value size on MacOS is 64 MB. On Linux it's
// much smaller at 64 KB. Unless the kernel is evil or buggy, we should never
// hit the limit.
maxBufSize = 64 * 1024 * 1024
// Function name as reported in error messages
myname = "xattr.get"
)
size := initialBufSize
for {
data := make([]byte, size)
read, err := getxattrFunc(name, data)
// If the buffer was too small to fit the value, Linux and MacOS react
// differently:
// Linux: returns an ERANGE error and "-1" bytes.
// MacOS: truncates the value and returns "size" bytes. If the value
// happens to be exactly as big as the buffer, we cannot know if it was
// truncated, and we retry with a bigger buffer. Contrary to documentation,
// MacOS never seems to return ERANGE!
// To keep the code simple, we always check both conditions, and sometimes
// double the buffer size without it being strictly necessary.
if err == syscall.ERANGE || read == size {
// The buffer was too small. Try again.
size <<= 1
if size >= maxBufSize {
return nil, &Error{myname, path, name, syscall.EOVERFLOW}
}
continue
}
if err != nil {
return nil, &Error{myname, path, name, err}
}
return data[:read], nil
}
}
// Set associates name and data together as an attribute of path.
func Set(path, name string, data []byte) error {
if err := setxattr(path, name, data, 0); err != nil {
return &Error{"xattr.Set", path, name, err}
}
return nil
}
// LSet is like Set but does not follow a symlink at
// the end of the path.
func LSet(path, name string, data []byte) error {
if err := lsetxattr(path, name, data, 0); err != nil {
return &Error{"xattr.LSet", path, name, err}
}
return nil
}
// FSet is like Set but accepts a os.File instead of a file path.
func FSet(f *os.File, name string, data []byte) error {
if err := fsetxattr(f, name, data, 0); err != nil {
return &Error{"xattr.FSet", f.Name(), name, err}
}
return nil
}
// SetWithFlags associates name and data together as an attribute of path.
// Forwards the flags parameter to the syscall layer.
func SetWithFlags(path, name string, data []byte, flags int) error {
if err := setxattr(path, name, data, flags); err != nil {
return &Error{"xattr.SetWithFlags", path, name, err}
}
return nil
}
// LSetWithFlags is like SetWithFlags but does not follow a symlink at
// the end of the path.
func LSetWithFlags(path, name string, data []byte, flags int) error {
if err := lsetxattr(path, name, data, flags); err != nil {
return &Error{"xattr.LSetWithFlags", path, name, err}
}
return nil
}
// FSetWithFlags is like SetWithFlags but accepts a os.File instead of a file path.
func FSetWithFlags(f *os.File, name string, data []byte, flags int) error {
if err := fsetxattr(f, name, data, flags); err != nil {
return &Error{"xattr.FSetWithFlags", f.Name(), name, err}
}
return nil
}
// Remove removes the attribute associated with the given path.
func Remove(path, name string) error {
if err := removexattr(path, name); err != nil {
return &Error{"xattr.Remove", path, name, err}
}
return nil
}
// LRemove is like Remove but does not follow a symlink at the end of the
// path.
func LRemove(path, name string) error {
if err := lremovexattr(path, name); err != nil {
return &Error{"xattr.LRemove", path, name, err}
}
return nil
}
// FRemove is like Remove but accepts a os.File instead of a file path.
func FRemove(f *os.File, name string) error {
if err := fremovexattr(f, name); err != nil {
return &Error{"xattr.FRemove", f.Name(), name, err}
}
return nil
}
// List retrieves a list of names of extended attributes associated
// with the given path in the file system.
func List(path string) ([]string, error) {
return list(path, func(data []byte) (int, error) {
return listxattr(path, data)
})
}
// LList is like List but does not follow a symlink at the end of the
// path.
func LList(path string) ([]string, error) {
return list(path, func(data []byte) (int, error) {
return llistxattr(path, data)
})
}
// FList is like List but accepts a os.File instead of a file path.
func FList(f *os.File) ([]string, error) {
return list(f.Name(), func(data []byte) (int, error) {
return flistxattr(f, data)
})
}
type listxattrFunc func(data []byte) (int, error)
// list contains the buffer allocation logic used by both List and LList.
func list(path string, listxattrFunc listxattrFunc) ([]string, error) {
myname := "xattr.list"
// find size.
size, err := listxattrFunc(nil)
if err != nil {
return nil, &Error{myname, path, "", err}
}
if size > 0 {
// `size + 1` because of ERANGE error when reading
// from a SMB1 mount point (https://github.com/pkg/xattr/issues/16).
buf := make([]byte, size+1)
// Read into buffer of that size.
read, err := listxattrFunc(buf)
if err != nil {
return nil, &Error{myname, path, "", err}
}
return stringsFromByteSlice(buf[:read]), nil
}
return []string{}, nil
}
// bytePtrFromSlice returns a pointer to array of bytes and a size.
func bytePtrFromSlice(data []byte) (ptr *byte, size int) {
size = len(data)
if size > 0 {
ptr = &data[0]
}
return
}

201
vendor/github.com/pkg/xattr/xattr_bsd.go generated vendored Normal file
View File

@ -0,0 +1,201 @@
//go:build freebsd || netbsd
// +build freebsd netbsd
package xattr
import (
"os"
"syscall"
"unsafe"
)
const (
// XATTR_SUPPORTED will be true if the current platform is supported
XATTR_SUPPORTED = true
EXTATTR_NAMESPACE_USER = 1
// ENOATTR is not exported by the syscall package on Linux, because it is
// an alias for ENODATA. We export it here so it is available on all
// our supported platforms.
ENOATTR = syscall.ENOATTR
)
func getxattr(path string, name string, data []byte) (int, error) {
return sysGet(syscall.SYS_EXTATTR_GET_FILE, path, name, data)
}
func lgetxattr(path string, name string, data []byte) (int, error) {
return sysGet(syscall.SYS_EXTATTR_GET_LINK, path, name, data)
}
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
return getxattr(f.Name(), name, data)
}
// sysGet is called by getxattr and lgetxattr with the appropriate syscall
// number. This works because syscalls have the same signature and return
// values.
func sysGet(syscallNum uintptr, path string, name string, data []byte) (int, error) {
ptr, nbytes := bytePtrFromSlice(data)
/*
ssize_t extattr_get_file(
const char *path,
int attrnamespace,
const char *attrname,
void *data,
size_t nbytes);
ssize_t extattr_get_link(
const char *path,
int attrnamespace,
const char *attrname,
void *data,
size_t nbytes);
*/
r0, _, err := syscall.Syscall6(syscallNum, uintptr(unsafe.Pointer(syscall.StringBytePtr(path))),
EXTATTR_NAMESPACE_USER, uintptr(unsafe.Pointer(syscall.StringBytePtr(name))),
uintptr(unsafe.Pointer(ptr)), uintptr(nbytes), 0)
if err != syscall.Errno(0) {
return int(r0), err
}
return int(r0), nil
}
func setxattr(path string, name string, data []byte, flags int) error {
return sysSet(syscall.SYS_EXTATTR_SET_FILE, path, name, data)
}
func lsetxattr(path string, name string, data []byte, flags int) error {
return sysSet(syscall.SYS_EXTATTR_SET_LINK, path, name, data)
}
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
return setxattr(f.Name(), name, data, flags)
}
// sysSet is called by setxattr and lsetxattr with the appropriate syscall
// number. This works because syscalls have the same signature and return
// values.
func sysSet(syscallNum uintptr, path string, name string, data []byte) error {
ptr, nbytes := bytePtrFromSlice(data)
/*
ssize_t extattr_set_file(
const char *path,
int attrnamespace,
const char *attrname,
const void *data,
size_t nbytes
);
ssize_t extattr_set_link(
const char *path,
int attrnamespace,
const char *attrname,
const void *data,
size_t nbytes
);
*/
r0, _, err := syscall.Syscall6(syscallNum, uintptr(unsafe.Pointer(syscall.StringBytePtr(path))),
EXTATTR_NAMESPACE_USER, uintptr(unsafe.Pointer(syscall.StringBytePtr(name))),
uintptr(unsafe.Pointer(ptr)), uintptr(nbytes), 0)
if err != syscall.Errno(0) {
return err
}
if int(r0) != nbytes {
return syscall.E2BIG
}
return nil
}
func removexattr(path string, name string) error {
return sysRemove(syscall.SYS_EXTATTR_DELETE_FILE, path, name)
}
func lremovexattr(path string, name string) error {
return sysRemove(syscall.SYS_EXTATTR_DELETE_LINK, path, name)
}
func fremovexattr(f *os.File, name string) error {
return removexattr(f.Name(), name)
}
// sysSet is called by removexattr and lremovexattr with the appropriate syscall
// number. This works because syscalls have the same signature and return
// values.
func sysRemove(syscallNum uintptr, path string, name string) error {
/*
int extattr_delete_file(
const char *path,
int attrnamespace,
const char *attrname
);
int extattr_delete_link(
const char *path,
int attrnamespace,
const char *attrname
);
*/
_, _, err := syscall.Syscall(syscallNum, uintptr(unsafe.Pointer(syscall.StringBytePtr(path))),
EXTATTR_NAMESPACE_USER, uintptr(unsafe.Pointer(syscall.StringBytePtr(name))),
)
if err != syscall.Errno(0) {
return err
}
return nil
}
func listxattr(path string, data []byte) (int, error) {
return sysList(syscall.SYS_EXTATTR_LIST_FILE, path, data)
}
func llistxattr(path string, data []byte) (int, error) {
return sysList(syscall.SYS_EXTATTR_LIST_LINK, path, data)
}
func flistxattr(f *os.File, data []byte) (int, error) {
return listxattr(f.Name(), data)
}
// sysSet is called by listxattr and llistxattr with the appropriate syscall
// number. This works because syscalls have the same signature and return
// values.
func sysList(syscallNum uintptr, path string, data []byte) (int, error) {
ptr, nbytes := bytePtrFromSlice(data)
/*
ssize_t extattr_list_file(
const char *path,
int attrnamespace,
void *data,
size_t nbytes
);
ssize_t extattr_list_link(
const char *path,
int attrnamespace,
void *data,
size_t nbytes
);
*/
r0, _, err := syscall.Syscall6(syscallNum, uintptr(unsafe.Pointer(syscall.StringBytePtr(path))),
EXTATTR_NAMESPACE_USER, uintptr(unsafe.Pointer(ptr)), uintptr(nbytes), 0, 0)
if err != syscall.Errno(0) {
return int(r0), err
}
return int(r0), nil
}
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On FreeBSD, each entry consists of a single byte containing the length
// of the attribute name, followed by the attribute name.
// The name is _not_ terminated by NULL.
func stringsFromByteSlice(buf []byte) (result []string) {
index := 0
for index < len(buf) {
next := index + 1 + int(buf[index])
result = append(result, string(buf[index+1:next]))
index = next
}
return
}

90
vendor/github.com/pkg/xattr/xattr_darwin.go generated vendored Normal file
View File

@ -0,0 +1,90 @@
//go:build darwin
// +build darwin
package xattr
import (
"os"
"syscall"
"golang.org/x/sys/unix"
)
// See https://opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/sys/xattr.h.auto.html
const (
// XATTR_SUPPORTED will be true if the current platform is supported
XATTR_SUPPORTED = true
XATTR_NOFOLLOW = 0x0001
XATTR_CREATE = 0x0002
XATTR_REPLACE = 0x0004
XATTR_NOSECURITY = 0x0008
XATTR_NODEFAULT = 0x0010
XATTR_SHOWCOMPRESSION = 0x0020
// ENOATTR is not exported by the syscall package on Linux, because it is
// an alias for ENODATA. We export it here so it is available on all
// our supported platforms.
ENOATTR = syscall.ENOATTR
)
func getxattr(path string, name string, data []byte) (int, error) {
return unix.Getxattr(path, name, data)
}
func lgetxattr(path string, name string, data []byte) (int, error) {
return unix.Lgetxattr(path, name, data)
}
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
return getxattr(f.Name(), name, data)
}
func setxattr(path string, name string, data []byte, flags int) error {
return unix.Setxattr(path, name, data, flags)
}
func lsetxattr(path string, name string, data []byte, flags int) error {
return unix.Lsetxattr(path, name, data, flags)
}
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
return setxattr(f.Name(), name, data, flags)
}
func removexattr(path string, name string) error {
return unix.Removexattr(path, name)
}
func lremovexattr(path string, name string) error {
return unix.Lremovexattr(path, name)
}
func fremovexattr(f *os.File, name string) error {
return removexattr(f.Name(), name)
}
func listxattr(path string, data []byte) (int, error) {
return unix.Listxattr(path, data)
}
func llistxattr(path string, data []byte) (int, error) {
return unix.Llistxattr(path, data)
}
func flistxattr(f *os.File, data []byte) (int, error) {
return listxattr(f.Name(), data)
}
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On Darwin and Linux, each entry is a NULL-terminated string.
func stringsFromByteSlice(buf []byte) (result []string) {
offset := 0
for index, b := range buf {
if b == 0 {
result = append(result, string(buf[offset:index]))
offset = index + 1
}
}
return
}

142
vendor/github.com/pkg/xattr/xattr_linux.go generated vendored Normal file
View File

@ -0,0 +1,142 @@
//go:build linux
// +build linux
package xattr
import (
"os"
"syscall"
"golang.org/x/sys/unix"
)
const (
// XATTR_SUPPORTED will be true if the current platform is supported
XATTR_SUPPORTED = true
XATTR_CREATE = unix.XATTR_CREATE
XATTR_REPLACE = unix.XATTR_REPLACE
// ENOATTR is not exported by the syscall package on Linux, because it is
// an alias for ENODATA. We export it here so it is available on all
// our supported platforms.
ENOATTR = syscall.ENODATA
)
// On Linux, FUSE and CIFS filesystems can return EINTR for interrupted system
// calls. This function works around this by retrying system calls until they
// stop returning EINTR.
//
// See https://github.com/golang/go/commit/6b420169d798c7ebe733487b56ea5c3fa4aab5ce.
func ignoringEINTR(fn func() error) (err error) {
for {
err = fn()
if err != unix.EINTR {
break
}
}
return err
}
func getxattr(path string, name string, data []byte) (int, error) {
var r int
err := ignoringEINTR(func() (err error) {
r, err = unix.Getxattr(path, name, data)
return err
})
return r, err
}
func lgetxattr(path string, name string, data []byte) (int, error) {
var r int
err := ignoringEINTR(func() (err error) {
r, err = unix.Lgetxattr(path, name, data)
return err
})
return r, err
}
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
var r int
err := ignoringEINTR(func() (err error) {
r, err = unix.Fgetxattr(int(f.Fd()), name, data)
return err
})
return r, err
}
func setxattr(path string, name string, data []byte, flags int) error {
return ignoringEINTR(func() (err error) {
return unix.Setxattr(path, name, data, flags)
})
}
func lsetxattr(path string, name string, data []byte, flags int) error {
return ignoringEINTR(func() (err error) {
return unix.Lsetxattr(path, name, data, flags)
})
}
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
return ignoringEINTR(func() (err error) {
return unix.Fsetxattr(int(f.Fd()), name, data, flags)
})
}
func removexattr(path string, name string) error {
return ignoringEINTR(func() (err error) {
return unix.Removexattr(path, name)
})
}
func lremovexattr(path string, name string) error {
return ignoringEINTR(func() (err error) {
return unix.Lremovexattr(path, name)
})
}
func fremovexattr(f *os.File, name string) error {
return ignoringEINTR(func() (err error) {
return unix.Fremovexattr(int(f.Fd()), name)
})
}
func listxattr(path string, data []byte) (int, error) {
var r int
err := ignoringEINTR(func() (err error) {
r, err = unix.Listxattr(path, data)
return err
})
return r, err
}
func llistxattr(path string, data []byte) (int, error) {
var r int
err := ignoringEINTR(func() (err error) {
r, err = unix.Llistxattr(path, data)
return err
})
return r, err
}
func flistxattr(f *os.File, data []byte) (int, error) {
var r int
err := ignoringEINTR(func() (err error) {
r, err = unix.Flistxattr(int(f.Fd()), data)
return err
})
return r, err
}
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On Darwin and Linux, each entry is a NULL-terminated string.
func stringsFromByteSlice(buf []byte) (result []string) {
offset := 0
for index, b := range buf {
if b == 0 {
result = append(result, string(buf[offset:index]))
offset = index + 1
}
}
return
}

165
vendor/github.com/pkg/xattr/xattr_solaris.go generated vendored Normal file
View File

@ -0,0 +1,165 @@
//go:build solaris
// +build solaris
package xattr
import (
"os"
"syscall"
"golang.org/x/sys/unix"
)
const (
// XATTR_SUPPORTED will be true if the current platform is supported
XATTR_SUPPORTED = true
XATTR_CREATE = 0x1
XATTR_REPLACE = 0x2
// ENOATTR is not exported by the syscall package on Linux, because it is
// an alias for ENODATA. We export it here so it is available on all
// our supported platforms.
ENOATTR = syscall.ENODATA
)
func getxattr(path string, name string, data []byte) (int, error) {
f, err := os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
return 0, err
}
defer func() {
_ = f.Close()
}()
return fgetxattr(f, name, data)
}
func lgetxattr(path string, name string, data []byte) (int, error) {
return 0, unix.ENOTSUP
}
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
fd, err := unix.Openat(int(f.Fd()), name, unix.O_RDONLY|unix.O_XATTR, 0)
if err != nil {
return 0, err
}
defer func() {
_ = unix.Close(fd)
}()
return unix.Read(fd, data)
}
func setxattr(path string, name string, data []byte, flags int) error {
f, err := os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
return err
}
err = fsetxattr(f, name, data, flags)
if err != nil {
_ = f.Close()
return err
}
return f.Close()
}
func lsetxattr(path string, name string, data []byte, flags int) error {
return unix.ENOTSUP
}
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
mode := unix.O_WRONLY | unix.O_XATTR
if flags&XATTR_REPLACE != 0 {
mode |= unix.O_TRUNC
} else if flags&XATTR_CREATE != 0 {
mode |= unix.O_CREAT | unix.O_EXCL
} else {
mode |= unix.O_CREAT | unix.O_TRUNC
}
fd, err := unix.Openat(int(f.Fd()), name, mode, 0666)
if err != nil {
return err
}
if _, err = unix.Write(fd, data); err != nil {
_ = unix.Close(fd)
return err
}
return unix.Close(fd)
}
func removexattr(path string, name string) error {
fd, err := unix.Open(path, unix.O_RDONLY|unix.O_XATTR, 0)
if err != nil {
return err
}
f := os.NewFile(uintptr(fd), path)
defer func() {
_ = f.Close()
}()
return fremovexattr(f, name)
}
func lremovexattr(path string, name string) error {
return unix.ENOTSUP
}
func fremovexattr(f *os.File, name string) error {
fd, err := unix.Openat(int(f.Fd()), ".", unix.O_XATTR, 0)
if err != nil {
return err
}
defer func() {
_ = unix.Close(fd)
}()
return unix.Unlinkat(fd, name, 0)
}
func listxattr(path string, data []byte) (int, error) {
f, err := os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
return 0, err
}
defer func() {
_ = f.Close()
}()
return flistxattr(f, data)
}
func llistxattr(path string, data []byte) (int, error) {
return 0, unix.ENOTSUP
}
func flistxattr(f *os.File, data []byte) (int, error) {
fd, err := unix.Openat(int(f.Fd()), ".", unix.O_RDONLY|unix.O_XATTR, 0)
if err != nil {
return 0, err
}
xf := os.NewFile(uintptr(fd), f.Name())
defer func() {
_ = xf.Close()
}()
names, err := xf.Readdirnames(-1)
if err != nil {
return 0, err
}
var buf []byte
for _, name := range names {
buf = append(buf, append([]byte(name), '\000')...)
}
if data == nil {
return len(buf), nil
}
return copy(data, buf), nil
}
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On Darwin and Linux, each entry is a NULL-terminated string.
func stringsFromByteSlice(buf []byte) (result []string) {
offset := 0
for index, b := range buf {
if b == 0 {
result = append(result, string(buf[offset:index]))
offset = index + 1
}
}
return
}

70
vendor/github.com/pkg/xattr/xattr_unsupported.go generated vendored Normal file
View File

@ -0,0 +1,70 @@
//go:build !linux && !freebsd && !netbsd && !darwin && !solaris
// +build !linux,!freebsd,!netbsd,!darwin,!solaris
package xattr
import (
"os"
"syscall"
)
const (
// We need to use the default for non supported operating systems
ENOATTR = syscall.ENODATA
)
// XATTR_SUPPORTED will be true if the current platform is supported
const XATTR_SUPPORTED = false
func getxattr(path string, name string, data []byte) (int, error) {
return 0, nil
}
func lgetxattr(path string, name string, data []byte) (int, error) {
return 0, nil
}
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
return 0, nil
}
func setxattr(path string, name string, data []byte, flags int) error {
return nil
}
func lsetxattr(path string, name string, data []byte, flags int) error {
return nil
}
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
return nil
}
func removexattr(path string, name string) error {
return nil
}
func lremovexattr(path string, name string) error {
return nil
}
func fremovexattr(f *os.File, name string) error {
return nil
}
func listxattr(path string, data []byte) (int, error) {
return 0, nil
}
func llistxattr(path string, data []byte) (int, error) {
return 0, nil
}
func flistxattr(f *os.File, data []byte) (int, error) {
return 0, nil
}
// dummy
func stringsFromByteSlice(buf []byte) (result []string) {
return []string{}
}