mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-05 16:47:27 -04: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
+2
-1
@@ -50,6 +50,7 @@ includes_Darwin='
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sys/xattr.h>
|
||||||
#include <net/bpf.h>
|
#include <net/bpf.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_types.h>
|
#include <net/if_types.h>
|
||||||
@@ -437,7 +438,7 @@ ccflags="$@"
|
|||||||
$2 ~ /^GENL_/ ||
|
$2 ~ /^GENL_/ ||
|
||||||
$2 ~ /^STATX_/ ||
|
$2 ~ /^STATX_/ ||
|
||||||
$2 ~ /^UTIME_/ ||
|
$2 ~ /^UTIME_/ ||
|
||||||
$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
|
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
|
||||||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
|
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
|
||||||
$2 ~ /^FSOPT_/ ||
|
$2 ~ /^FSOPT_/ ||
|
||||||
$2 ~ /^WDIOC_/ ||
|
$2 ~ /^WDIOC_/ ||
|
||||||
|
|||||||
+26
-15
@@ -176,9 +176,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
|
func xattrPointer(dest []byte) *byte {
|
||||||
|
|
||||||
func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
|
|
||||||
// It's only when dest is set to NULL that the OS X implementations of
|
// 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.
|
// 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
|
// 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 {
|
if len(dest) > 0 {
|
||||||
destp = &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)
|
//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
|
// current implementation, only the resource fork extended attribute makes
|
||||||
// use of this argument. For all others, position is reserved. We simply
|
// use of this argument. For all others, position is reserved. We simply
|
||||||
// default to setting it to zero.
|
// default to setting it to zero.
|
||||||
var datap *byte
|
return setxattr(path, attr, xattrPointer(data), len(data), 0, flags)
|
||||||
if len(data) > 0 {
|
}
|
||||||
datap = &data[0]
|
|
||||||
}
|
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
|
||||||
return setxattr(path, attr, datap, len(data), 0, flags)
|
return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys removexattr(path string, attr string, options int) (err error)
|
//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)
|
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)
|
//sys listxattr(path string, dest *byte, size int, options int) (sz int, err error)
|
||||||
|
|
||||||
func Listxattr(path string, dest []byte) (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.
|
return listxattr(path, xattrPointer(dest), len(dest), 0)
|
||||||
var destp *byte
|
}
|
||||||
if len(dest) > 0 {
|
|
||||||
destp = &dest[0]
|
func Llistxattr(link string, dest []byte) (sz int, err error) {
|
||||||
}
|
return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)
|
||||||
return listxattr(path, destp, len(dest), 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
package unix_test
|
package unix_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -89,4 +90,29 @@ func TestXattr(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Removexattr: %v", err)
|
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
|
WORDSIZE = 0x20
|
||||||
WSTOPPED = 0x8
|
WSTOPPED = 0x8
|
||||||
WUNTRACED = 0x2
|
WUNTRACED = 0x2
|
||||||
|
XATTR_CREATE = 0x2
|
||||||
|
XATTR_NODEFAULT = 0x10
|
||||||
|
XATTR_NOFOLLOW = 0x1
|
||||||
|
XATTR_NOSECURITY = 0x8
|
||||||
|
XATTR_REPLACE = 0x4
|
||||||
|
XATTR_SHOWCOMPRESSION = 0x20
|
||||||
)
|
)
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
|
|||||||
@@ -1473,6 +1473,12 @@ const (
|
|||||||
WORDSIZE = 0x40
|
WORDSIZE = 0x40
|
||||||
WSTOPPED = 0x8
|
WSTOPPED = 0x8
|
||||||
WUNTRACED = 0x2
|
WUNTRACED = 0x2
|
||||||
|
XATTR_CREATE = 0x2
|
||||||
|
XATTR_NODEFAULT = 0x10
|
||||||
|
XATTR_NOFOLLOW = 0x1
|
||||||
|
XATTR_NOSECURITY = 0x8
|
||||||
|
XATTR_REPLACE = 0x4
|
||||||
|
XATTR_SHOWCOMPRESSION = 0x20
|
||||||
)
|
)
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
|
|||||||
@@ -1473,6 +1473,12 @@ const (
|
|||||||
WORDSIZE = 0x40
|
WORDSIZE = 0x40
|
||||||
WSTOPPED = 0x8
|
WSTOPPED = 0x8
|
||||||
WUNTRACED = 0x2
|
WUNTRACED = 0x2
|
||||||
|
XATTR_CREATE = 0x2
|
||||||
|
XATTR_NODEFAULT = 0x10
|
||||||
|
XATTR_NOFOLLOW = 0x1
|
||||||
|
XATTR_NOSECURITY = 0x8
|
||||||
|
XATTR_REPLACE = 0x4
|
||||||
|
XATTR_SHOWCOMPRESSION = 0x20
|
||||||
)
|
)
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
|
|||||||
@@ -1473,6 +1473,12 @@ const (
|
|||||||
WORDSIZE = 0x40
|
WORDSIZE = 0x40
|
||||||
WSTOPPED = 0x8
|
WSTOPPED = 0x8
|
||||||
WUNTRACED = 0x2
|
WUNTRACED = 0x2
|
||||||
|
XATTR_CREATE = 0x2
|
||||||
|
XATTR_NODEFAULT = 0x10
|
||||||
|
XATTR_NOFOLLOW = 0x1
|
||||||
|
XATTR_NOSECURITY = 0x8
|
||||||
|
XATTR_REPLACE = 0x4
|
||||||
|
XATTR_SHOWCOMPRESSION = 0x20
|
||||||
)
|
)
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
|
|||||||
Reference in New Issue
Block a user