unix: add F*xattr on Darwin

Add Fgetxattr, Flistxattr, Fremovexattr and Fsetxattr on Darwin. Also
add a corresponding test.

Updates golang/go#26832

Change-Id: Id75bfce90ccc024b567a7b066a9188a615b9eec4
Reviewed-on: https://go-review.googlesource.com/128537
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:
Tobias Klauser
2018-08-08 15:40:34 +00:00
committed by Tobias Klauser
parent 3249cb6984
commit 904bdc2570
6 changed files with 336 additions and 6 deletions
+82
View File
@@ -7,6 +7,7 @@
package unix_test
import (
"io/ioutil"
"os"
"runtime"
"strings"
@@ -117,3 +118,84 @@ func TestXattr(t *testing.T) {
}
}
}
func TestFdXattr(t *testing.T) {
file, err := ioutil.TempFile("", "TestFdXattr")
if err != nil {
t.Fatal(err)
}
defer os.Remove(file.Name())
defer file.Close()
fd := int(file.Fd())
xattrName := "user.test"
xattrDataSet := "gopher"
err = unix.Fsetxattr(fd, xattrName, []byte(xattrDataSet), 0)
if err == unix.ENOTSUP || err == unix.EOPNOTSUPP {
t.Skip("filesystem does not support extended attributes, skipping test")
} else if err != nil {
t.Fatalf("Fsetxattr: %v", err)
}
// find size
size, err := unix.Flistxattr(fd, nil)
if err != nil {
t.Fatalf("Flistxattr: %v", err)
}
if size <= 0 {
t.Fatalf("Flistxattr returned an empty list of attributes")
}
buf := make([]byte, size)
read, err := unix.Flistxattr(fd, buf)
if err != nil {
t.Fatalf("Flistxattr: %v", err)
}
xattrs := stringsFromByteSlice(buf[:read])
xattrWant := xattrName
if runtime.GOOS == "freebsd" {
// On FreeBSD, the namespace is stored separately from the xattr
// name and Listxattr doesn't return the namespace prefix.
xattrWant = strings.TrimPrefix(xattrWant, "user.")
}
found := false
for _, name := range xattrs {
if name == xattrWant {
found = true
}
}
if !found {
t.Errorf("Flistxattr did not return previously set attribute '%s'", xattrName)
}
// find size
size, err = unix.Fgetxattr(fd, xattrName, nil)
if err != nil {
t.Fatalf("Fgetxattr: %v", err)
}
if size <= 0 {
t.Fatalf("Fgetxattr returned an empty attribute")
}
xattrDataGet := make([]byte, size)
_, err = unix.Fgetxattr(fd, xattrName, xattrDataGet)
if err != nil {
t.Fatalf("Fgetxattr: %v", err)
}
got := string(xattrDataGet)
if got != xattrDataSet {
t.Errorf("Fgetxattr: expected attribute value %s, got %s", xattrDataSet, got)
}
err = unix.Fremovexattr(fd, xattrName)
if err != nil {
t.Fatalf("Fremovexattr: %v", err)
}
}