From 2d3aea8623c58a420085eb0b3db2ea9ebd9089d0 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Thu, 17 Mar 2016 13:41:08 -0400 Subject: [PATCH] xattr: simple wrapper for syscalls Signed-off-by: Vincent Batts --- xattr/xattr.go | 35 +++++++++++++++++++++++++++++++++++ xattr/xattr_test.go | 38 ++++++++++++++++++++++++++++++++++++++ xattr/xattr_unsupported.go | 13 +++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 xattr/xattr.go create mode 100644 xattr/xattr_test.go create mode 100644 xattr/xattr_unsupported.go diff --git a/xattr/xattr.go b/xattr/xattr.go new file mode 100644 index 0000000..3e2b53b --- /dev/null +++ b/xattr/xattr.go @@ -0,0 +1,35 @@ +// +build linux + +package xattr + +import ( + "strings" + "syscall" +) + +// Get returns the extended attributes (xattr) on file `path`, for the given `name`. +func Get(path, name string) ([]byte, error) { + dest := make([]byte, 1024) + i, err := syscall.Getxattr(path, name, dest) + if err != nil { + return nil, err + } + return dest[:i], nil +} + +// Set sets the extended attributes (xattr) on file `path`, for the given `name` and `value` +func Set(path, name string, value []byte) error { + return syscall.Setxattr(path, name, value, 0) +} + +// List returns a list of all the extended attributes (xattr) for file `path` +func List(path string) ([]string, error) { + dest := make([]byte, 1024) + i, err := syscall.Listxattr(path, dest) + if err != nil { + return nil, err + } + return strings.Split(strings.TrimRight(string(dest[:i]), nilByte), nilByte), nil +} + +const nilByte = "\x00" diff --git a/xattr/xattr_test.go b/xattr/xattr_test.go new file mode 100644 index 0000000..ae8f616 --- /dev/null +++ b/xattr/xattr_test.go @@ -0,0 +1,38 @@ +package xattr + +import ( + "bytes" + "io/ioutil" + "os" + "testing" +) + +func TestXattr(t *testing.T) { + fh, err := ioutil.TempFile(".", "xattr.") + if err != nil { + t.Fatal(err) + } + defer os.Remove(fh.Name()) + if err := fh.Close(); err != nil { + t.Fatal(err) + } + + expected := []byte("1234") + if err := Set(fh.Name(), "user.testing", expected); err != nil { + t.Fatal(fh.Name(), err) + } + l, err := List(fh.Name()) + if err != nil { + t.Error(fh.Name(), err) + } + if !(len(l) > 0) { + t.Errorf("%q: expected a list of at least 1; got %d", len(l)) + } + got, err := Get(fh.Name(), "user.testing") + if err != nil { + t.Fatal(fh.Name(), err) + } + if !bytes.Equal(got, expected) { + t.Errorf("%q: expected %q; got %q", fh.Name(), expected, got) + } +} diff --git a/xattr/xattr_unsupported.go b/xattr/xattr_unsupported.go new file mode 100644 index 0000000..abf617d --- /dev/null +++ b/xattr/xattr_unsupported.go @@ -0,0 +1,13 @@ +// +build !linux + +package xattr + +func Get(path, name string) ([]byte, error) { + return nil, nil +} +func Set(path, name string, value []byte) error { + return nil +} +func List(path string) ([]string, error) { + return nil, nil +}