Use symlink xattr functions from x/sys/unix

Use the symlink xattr syscall wrappers Lgetxattr, Llistxattr and
Lsetxattr from x/sys/unix (introduced in
golang/sys@b90f89a1e7) instead of
providing own wrappers. Leave the functionality of system.Lgetxattr
intact with respect to the retry with a larger buffer, but switch it to
use unix.Lgetxattr.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
This commit is contained in:
Tobias Klauser 2017-05-30 16:32:06 +02:00
parent f0ae35b9e7
commit d8b5c1c810
2 changed files with 12 additions and 77 deletions

View File

@ -1,54 +1,14 @@
package system package system
import ( import "golang.org/x/sys/unix"
"unsafe"
"golang.org/x/sys/unix"
)
var _zero uintptr
// Returns the size of xattrs and nil error
// Requires path, takes allocated []byte or nil as last argument
func Llistxattr(path string, dest []byte) (size int, err error) {
pathBytes, err := unix.BytePtrFromString(path)
if err != nil {
return -1, err
}
var newpathBytes unsafe.Pointer
if len(dest) > 0 {
newpathBytes = unsafe.Pointer(&dest[0])
} else {
newpathBytes = unsafe.Pointer(&_zero)
}
_size, _, errno := unix.Syscall6(unix.SYS_LLISTXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(newpathBytes), uintptr(len(dest)), 0, 0, 0)
size = int(_size)
if errno != 0 {
return -1, errno
}
return size, nil
}
// Returns a []byte slice if the xattr is set and nil otherwise // Returns a []byte slice if the xattr is set and nil otherwise
// Requires path and its attribute as arguments // Requires path and its attribute as arguments
func Lgetxattr(path string, attr string) ([]byte, error) { func Lgetxattr(path string, attr string) ([]byte, error) {
var sz int var sz int
pathBytes, err := unix.BytePtrFromString(path)
if err != nil {
return nil, err
}
attrBytes, err := unix.BytePtrFromString(attr)
if err != nil {
return nil, err
}
// Start with a 128 length byte array // Start with a 128 length byte array
sz = 128 dest := make([]byte, 128)
dest := make([]byte, sz) sz, errno := unix.Lgetxattr(path, attr, dest)
destBytes := unsafe.Pointer(&dest[0])
_sz, _, errno := unix.Syscall6(unix.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
switch { switch {
case errno == unix.ENODATA: case errno == unix.ENODATA:
@ -57,44 +17,19 @@ func Lgetxattr(path string, attr string) ([]byte, error) {
return nil, errno return nil, errno
case errno == unix.ERANGE: case errno == unix.ERANGE:
// 128 byte array might just not be good enough, // 128 byte array might just not be good enough,
// A dummy buffer is used ``uintptr(0)`` to get real size // A dummy buffer is used to get the real size
// of the xattrs on disk // of the xattrs on disk
_sz, _, errno = unix.Syscall6(unix.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0) sz, errno = unix.Lgetxattr(path, attr, []byte{})
sz = int(_sz) if errno != nil {
if sz < 0 {
return nil, errno return nil, errno
} }
dest = make([]byte, sz) dest = make([]byte, sz)
destBytes := unsafe.Pointer(&dest[0]) sz, errno = unix.Lgetxattr(path, attr, dest)
_sz, _, errno = unix.Syscall6(unix.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) if errno != nil {
if errno != 0 {
return nil, errno return nil, errno
} }
case errno != 0: case errno != nil:
return nil, errno return nil, errno
} }
sz = int(_sz)
return dest[:sz], nil return dest[:sz], nil
} }
func Lsetxattr(path string, attr string, data []byte, flags int) error {
pathBytes, err := unix.BytePtrFromString(path)
if err != nil {
return err
}
attrBytes, err := unix.BytePtrFromString(attr)
if err != nil {
return err
}
var dataBytes unsafe.Pointer
if len(data) > 0 {
dataBytes = unsafe.Pointer(&data[0])
} else {
dataBytes = unsafe.Pointer(&_zero)
}
_, _, errno := unix.Syscall6(unix.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
if errno != 0 {
return errno
}
return nil
}

View File

@ -27,12 +27,12 @@ func stringsfromByte(buf []byte) (result []string) {
} }
func Listxattr(path string) ([]string, error) { func Listxattr(path string) ([]string, error) {
size, err := system.Llistxattr(path, nil) size, err := unix.Llistxattr(path, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
buf := make([]byte, size) buf := make([]byte, size)
read, err := system.Llistxattr(path, buf) read, err := unix.Llistxattr(path, buf)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -49,5 +49,5 @@ func Getxattr(path, attr string) (string, error) {
} }
func Setxattr(path, xattr, value string) error { func Setxattr(path, xattr, value string) error {
return system.Lsetxattr(path, xattr, []byte(value), 0) return unix.Lsetxattr(path, xattr, []byte(value), 0)
} }