mirror of
https://github.com/golang/sys.git
synced 2026-02-09 04:06:04 +03:00
unix: add symlink-safe *xattr functions on darwin
Updates golang/go#14456 Change-Id: I04632ef1d302e938a2cc373eb90f600f01404380 Reviewed-on: https://go-review.googlesource.com/114198 Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
committed by
Tobias Klauser
parent
f3b0f5faf5
commit
77b0e43150
@@ -50,6 +50,7 @@ includes_Darwin='
|
||||
#include <sys/mount.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
@@ -437,7 +438,7 @@ ccflags="$@"
|
||||
$2 ~ /^GENL_/ ||
|
||||
$2 ~ /^STATX_/ ||
|
||||
$2 ~ /^UTIME_/ ||
|
||||
$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
|
||||
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
|
||||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
|
||||
$2 ~ /^FSOPT_/ ||
|
||||
$2 ~ /^WDIOC_/ ||
|
||||
|
||||
@@ -176,9 +176,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
|
||||
|
||||
func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
|
||||
func xattrPointer(dest []byte) *byte {
|
||||
// It's only when dest is set to NULL that the OS X implementations of
|
||||
// getxattr() and listxattr() return the current sizes of the named attributes.
|
||||
// An empty byte array is not sufficient. To maintain the same behaviour as the
|
||||
@@ -188,7 +186,17 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
|
||||
if len(dest) > 0 {
|
||||
destp = &dest[0]
|
||||
}
|
||||
return getxattr(path, attr, destp, len(dest), 0, 0)
|
||||
return destp
|
||||
}
|
||||
|
||||
//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
|
||||
|
||||
func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
|
||||
return getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0)
|
||||
}
|
||||
|
||||
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
|
||||
return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
//sys setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error)
|
||||
@@ -220,11 +228,11 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
|
||||
// current implementation, only the resource fork extended attribute makes
|
||||
// use of this argument. For all others, position is reserved. We simply
|
||||
// default to setting it to zero.
|
||||
var datap *byte
|
||||
if len(data) > 0 {
|
||||
datap = &data[0]
|
||||
}
|
||||
return setxattr(path, attr, datap, len(data), 0, flags)
|
||||
return setxattr(path, attr, xattrPointer(data), len(data), 0, flags)
|
||||
}
|
||||
|
||||
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
|
||||
return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
//sys removexattr(path string, attr string, options int) (err error)
|
||||
@@ -236,15 +244,18 @@ func Removexattr(path string, attr string) (err error) {
|
||||
return removexattr(path, attr, 0)
|
||||
}
|
||||
|
||||
func Lremovexattr(link string, attr string) (err error) {
|
||||
return removexattr(link, attr, XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
//sys listxattr(path string, dest *byte, size int, options int) (sz int, err error)
|
||||
|
||||
func Listxattr(path string, dest []byte) (sz int, err error) {
|
||||
// See comment in Getxattr for as to why Listxattr is implemented as such.
|
||||
var destp *byte
|
||||
if len(dest) > 0 {
|
||||
destp = &dest[0]
|
||||
}
|
||||
return listxattr(path, destp, len(dest), 0)
|
||||
return listxattr(path, xattrPointer(dest), len(dest), 0)
|
||||
}
|
||||
|
||||
func Llistxattr(link string, dest []byte) (sz int, err error) {
|
||||
return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -89,4 +90,29 @@ func TestXattr(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Removexattr: %v", err)
|
||||
}
|
||||
|
||||
n := "nonexistent"
|
||||
err = unix.Lsetxattr(n, xattrName, []byte(xattrDataSet), 0)
|
||||
if err != unix.ENOENT {
|
||||
t.Errorf("Lsetxattr: expected %v on non-existent file, got %v", unix.ENOENT, err)
|
||||
}
|
||||
|
||||
_, err = unix.Lgetxattr(n, xattrName, nil)
|
||||
if err != unix.ENOENT {
|
||||
t.Errorf("Lgetxattr: %v", err)
|
||||
}
|
||||
|
||||
s := "symlink1"
|
||||
err = os.Symlink(n, s)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Linux doesn't support xattrs on symlink according to xattr(7), so
|
||||
// just test that we get the proper errors.
|
||||
|
||||
err = unix.Lsetxattr(s, xattrName, []byte(xattrDataSet), 0)
|
||||
if err != nil && (runtime.GOOS != "linux" || err != unix.EPERM) {
|
||||
t.Fatalf("Lsetxattr: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1473,6 +1473,12 @@ const (
|
||||
WORDSIZE = 0x20
|
||||
WSTOPPED = 0x8
|
||||
WUNTRACED = 0x2
|
||||
XATTR_CREATE = 0x2
|
||||
XATTR_NODEFAULT = 0x10
|
||||
XATTR_NOFOLLOW = 0x1
|
||||
XATTR_NOSECURITY = 0x8
|
||||
XATTR_REPLACE = 0x4
|
||||
XATTR_SHOWCOMPRESSION = 0x20
|
||||
)
|
||||
|
||||
// Errors
|
||||
|
||||
@@ -1473,6 +1473,12 @@ const (
|
||||
WORDSIZE = 0x40
|
||||
WSTOPPED = 0x8
|
||||
WUNTRACED = 0x2
|
||||
XATTR_CREATE = 0x2
|
||||
XATTR_NODEFAULT = 0x10
|
||||
XATTR_NOFOLLOW = 0x1
|
||||
XATTR_NOSECURITY = 0x8
|
||||
XATTR_REPLACE = 0x4
|
||||
XATTR_SHOWCOMPRESSION = 0x20
|
||||
)
|
||||
|
||||
// Errors
|
||||
|
||||
@@ -1473,6 +1473,12 @@ const (
|
||||
WORDSIZE = 0x40
|
||||
WSTOPPED = 0x8
|
||||
WUNTRACED = 0x2
|
||||
XATTR_CREATE = 0x2
|
||||
XATTR_NODEFAULT = 0x10
|
||||
XATTR_NOFOLLOW = 0x1
|
||||
XATTR_NOSECURITY = 0x8
|
||||
XATTR_REPLACE = 0x4
|
||||
XATTR_SHOWCOMPRESSION = 0x20
|
||||
)
|
||||
|
||||
// Errors
|
||||
|
||||
@@ -1473,6 +1473,12 @@ const (
|
||||
WORDSIZE = 0x40
|
||||
WSTOPPED = 0x8
|
||||
WUNTRACED = 0x2
|
||||
XATTR_CREATE = 0x2
|
||||
XATTR_NODEFAULT = 0x10
|
||||
XATTR_NOFOLLOW = 0x1
|
||||
XATTR_NOSECURITY = 0x8
|
||||
XATTR_REPLACE = 0x4
|
||||
XATTR_SHOWCOMPRESSION = 0x20
|
||||
)
|
||||
|
||||
// Errors
|
||||
|
||||
Reference in New Issue
Block a user