Update github.com/pkg/xattr

Closes #843
This commit is contained in:
Alexander Neumann 2017-03-04 14:23:15 +01:00
parent 7066cc17bb
commit 82458d4de0
6 changed files with 88 additions and 62 deletions

2
vendor/manifest vendored
View File

@ -52,7 +52,7 @@
{ {
"importpath": "github.com/pkg/xattr", "importpath": "github.com/pkg/xattr",
"repository": "https://github.com/pkg/xattr", "repository": "https://github.com/pkg/xattr",
"revision": "1d40b70a947cd8e8457e4715e1123f8e99f5f241", "revision": "b867675798fa7708a444945602b452ca493f2272",
"branch": "master" "branch": "master"
}, },
{ {

View File

@ -1,3 +1,7 @@
[![GoDoc](https://godoc.org/github.com/pkg/xattr?status.svg)](http://godoc.org/github.com/pkg/xattr)
[![Go Report Card](https://goreportcard.com/badge/github.com/pkg/xattr)](https://goreportcard.com/report/github.com/pkg/xattr)
[![Build Status](https://travis-ci.org/pkg/xattr.svg?branch=master)](https://travis-ci.org/pkg/xattr)
xattr xattr
===== =====
Extended attribute support for Go (linux + darwin + freebsd). Extended attribute support for Go (linux + darwin + freebsd).
@ -10,12 +14,12 @@ Extended attribute support for Go (linux + darwin + freebsd).
const path = "/tmp/myfile" const path = "/tmp/myfile"
const prefix = "user." const prefix = "user."
if err = Setxattr(path, prefix+"test", []byte("test-attr-value")); err != nil { if err := xattr.Setxattr(path, prefix+"test", []byte("test-attr-value")); err != nil {
t.Fatal(err) log.Fatal(err)
} }
var data []byte var data []byte
data, err = Getxattr(path, prefix+"test"); err != nil { data, err = xattr.Getxattr(path, prefix+"test"); err != nil {
t.Fatal(err) log.Fatal(err)
} }
``` ```

View File

@ -1,3 +1,10 @@
/*
Package xattr provides support for extended attributes on linux, darwin and freebsd.
Extended attributes are name:value pairs associated permanently with files and directories,
similar to the environment strings associated with a process.
An attribute may be defined or undefined. If it is defined, its value may be empty or non-empty.
More details you can find here: https://en.wikipedia.org/wiki/Extended_file_attributes
*/
package xattr package xattr
// XAttrError records an error and the operation, file path and attribute that caused it. // XAttrError records an error and the operation, file path and attribute that caused it.
@ -12,8 +19,7 @@ func (e *XAttrError) Error() string {
return e.Op + " " + e.Path + " " + e.Name + ": " + e.Err.Error() return e.Op + " " + e.Path + " " + e.Name + ": " + e.Err.Error()
} }
// Convert an array of NULL terminated UTF-8 strings // nullTermToStrings converts an array of NULL terminated UTF-8 strings to a []string.
// to a []string.
func nullTermToStrings(buf []byte) (result []string) { func nullTermToStrings(buf []byte) (result []string) {
offset := 0 offset := 0
for index, b := range buf { for index, b := range buf {

View File

@ -2,44 +2,47 @@
package xattr package xattr
// Retrieve extended attribute data associated with path. // Getxattr retrieves extended attribute data associated with path.
func Getxattr(path, name string) ([]byte, error) { func Getxattr(path, name string) ([]byte, error) {
// find size. // find size.
size, err := getxattr(path, name, nil, 0, 0, 0) size, err := getxattr(path, name, nil, 0, 0, 0)
if err != nil { if err != nil {
return nil, &XAttrError{"getxattr", path, name, err} return nil, &XAttrError{"getxattr", path, name, err}
} }
buf := make([]byte, size) if size > 0 {
// Read into buffer of that size. buf := make([]byte, size)
read, err := getxattr(path, name, &buf[0], size, 0, 0) // Read into buffer of that size.
if err != nil { read, err := getxattr(path, name, &buf[0], size, 0, 0)
return nil, &XAttrError{"getxattr", path, name, err} if err != nil {
return nil, &XAttrError{"getxattr", path, name, err}
}
return buf[:read], nil
} }
return buf[:read], nil return []byte{}, nil
} }
// Retrieves a list of names of extended attributes associated with the // Listxattr retrieves a list of names of extended attributes associated
// given path in the file system. // with the given path in the file system.
func Listxattr(path string) ([]string, error) { func Listxattr(path string) ([]string, error) {
// find size. // find size.
size, err := listxattr(path, nil, 0, 0) size, err := listxattr(path, nil, 0, 0)
if err != nil { if err != nil {
return nil, &XAttrError{"listxattr", path, "", err} return nil, &XAttrError{"listxattr", path, "", err}
} }
if size == 0 { if size > 0 {
return []string{}, nil
}
buf := make([]byte, size) buf := make([]byte, size)
// Read into buffer of that size. // Read into buffer of that size.
read, err := listxattr(path, &buf[0], size, 0) read, err := listxattr(path, &buf[0], size, 0)
if err != nil { if err != nil {
return nil, &XAttrError{"listxattr", path, "", err} return nil, &XAttrError{"listxattr", path, "", err}
}
return nullTermToStrings(buf[:read]), nil
} }
return nullTermToStrings(buf[:read]), nil return []string{}, nil
} }
// Associates name and data together as an attribute of path. // Setxattr associates name and data together as an attribute of path.
func Setxattr(path, name string, data []byte) error { func Setxattr(path, name string, data []byte) error {
if err := setxattr(path, name, &data[0], len(data), 0, 0); err != nil { if err := setxattr(path, name, &data[0], len(data), 0, 0); err != nil {
return &XAttrError{"setxattr", path, name, err} return &XAttrError{"setxattr", path, name, err}
@ -47,7 +50,7 @@ func Setxattr(path, name string, data []byte) error {
return nil return nil
} }
// Remove the attribute. // Removexattr removes the attribute associated with the given path.
func Removexattr(path, name string) error { func Removexattr(path, name string) error {
if err := removexattr(path, name, 0); err != nil { if err := removexattr(path, name, 0); err != nil {
return &XAttrError{"removexattr", path, name, err} return &XAttrError{"removexattr", path, name, err}

View File

@ -10,40 +10,46 @@ const (
EXTATTR_NAMESPACE_USER = 1 EXTATTR_NAMESPACE_USER = 1
) )
// Retrieve extended attribute data associated with path. // Getxattr retrieves extended attribute data associated with path.
func Getxattr(path, name string) ([]byte, error) { func Getxattr(path, name string) ([]byte, error) {
// find size. // find size.
size, err := extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, nil, 0) size, err := extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, nil, 0)
if err != nil { if err != nil {
return nil, &XAttrError{"extattr_get_file", path, name, err} return nil, &XAttrError{"extattr_get_file", path, name, err}
} }
buf := make([]byte, size) if size > 0 {
// Read into buffer of that size. buf := make([]byte, size)
read, err := extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, &buf[0], size) // Read into buffer of that size.
if err != nil { read, err := extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, &buf[0], size)
return nil, &XAttrError{"extattr_get_file", path, name, err} if err != nil {
return nil, &XAttrError{"extattr_get_file", path, name, err}
}
return buf[:read], nil
} }
return buf[:read], nil return []byte{}, nil
} }
// Retrieves a list of names of extended attributes associated with the // Listxattr retrieves a list of names of extended attributes associated
// given path in the file system. // with the given path in the file system.
func Listxattr(path string) ([]string, error) { func Listxattr(path string) ([]string, error) {
// find size. // find size.
size, err := extattr_list_file(path, EXTATTR_NAMESPACE_USER, nil, 0) size, err := extattr_list_file(path, EXTATTR_NAMESPACE_USER, nil, 0)
if err != nil { if err != nil {
return nil, &XAttrError{"extattr_list_file", path, "", err} return nil, &XAttrError{"extattr_list_file", path, "", err}
} }
buf := make([]byte, size) if size > 0 {
// Read into buffer of that size. buf := make([]byte, size)
read, err := extattr_list_file(path, EXTATTR_NAMESPACE_USER, &buf[0], size) // Read into buffer of that size.
if err != nil { read, err := extattr_list_file(path, EXTATTR_NAMESPACE_USER, &buf[0], size)
return nil, &XAttrError{"extattr_list_file", path, "", err} if err != nil {
return nil, &XAttrError{"extattr_list_file", path, "", err}
}
return attrListToStrings(buf[:read]), nil
} }
return attrListToStrings(buf[:read]), nil return []string{}, nil
} }
// Associates name and data together as an attribute of path. // Setxattr associates name and data together as an attribute of path.
func Setxattr(path, name string, data []byte) error { func Setxattr(path, name string, data []byte) error {
written, err := extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, &data[0], len(data)) written, err := extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, &data[0], len(data))
if err != nil { if err != nil {
@ -55,7 +61,7 @@ func Setxattr(path, name string, data []byte) error {
return nil return nil
} }
// Remove the attribute. // Removexattr removes the attribute associated with the given path.
func Removexattr(path, name string) error { func Removexattr(path, name string) error {
if err := extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name); err != nil { if err := extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name); err != nil {
return &XAttrError{"extattr_delete_file", path, name, err} return &XAttrError{"extattr_delete_file", path, name, err}
@ -63,7 +69,7 @@ func Removexattr(path, name string) error {
return nil return nil
} }
// Convert a sequnce of attribute name entries to a []string. // attrListToStrings converts a sequnce of attribute name entries to a []string.
// Each entry consists of a single byte containing the length // Each entry consists of a single byte containing the length
// of the attribute name, followed by the attribute name. // of the attribute name, followed by the attribute name.
// The name is _not_ terminated by NUL. // The name is _not_ terminated by NUL.

View File

@ -4,40 +4,46 @@ package xattr
import "syscall" import "syscall"
// Retrieve extended attribute data associated with path. // Getxattr retrieves extended attribute data associated with path.
func Getxattr(path, name string) ([]byte, error) { func Getxattr(path, name string) ([]byte, error) {
// find size. // find size.
size, err := syscall.Getxattr(path, name, nil) size, err := syscall.Getxattr(path, name, nil)
if err != nil { if err != nil {
return nil, &XAttrError{"getxattr", path, name, err} return nil, &XAttrError{"getxattr", path, name, err}
} }
data := make([]byte, size) if size > 0 {
// Read into buffer of that size. data := make([]byte, size)
read, err := syscall.Getxattr(path, name, data) // Read into buffer of that size.
if err != nil { read, err := syscall.Getxattr(path, name, data)
return nil, &XAttrError{"getxattr", path, name, err} if err != nil {
return nil, &XAttrError{"getxattr", path, name, err}
}
return data[:read], nil
} }
return data[:read], nil return []byte{}, nil
} }
// Retrieves a list of names of extended attributes associated with the // Listxattr retrieves a list of names of extended attributes associated
// given path in the file system. // with the given path in the file system.
func Listxattr(path string) ([]string, error) { func Listxattr(path string) ([]string, error) {
// find size. // find size.
size, err := syscall.Listxattr(path, nil) size, err := syscall.Listxattr(path, nil)
if err != nil { if err != nil {
return nil, &XAttrError{"listxattr", path, "", err} return nil, &XAttrError{"listxattr", path, "", err}
} }
buf := make([]byte, size) if size > 0 {
// Read into buffer of that size. buf := make([]byte, size)
read, err := syscall.Listxattr(path, buf) // Read into buffer of that size.
if err != nil { read, err := syscall.Listxattr(path, buf)
return nil, &XAttrError{"listxattr", path, "", err} if err != nil {
return nil, &XAttrError{"listxattr", path, "", err}
}
return nullTermToStrings(buf[:read]), nil
} }
return nullTermToStrings(buf[:read]), nil return []string{}, nil
} }
// Associates name and data together as an attribute of path. // Setxattr associates name and data together as an attribute of path.
func Setxattr(path, name string, data []byte) error { func Setxattr(path, name string, data []byte) error {
if err := syscall.Setxattr(path, name, data, 0); err != nil { if err := syscall.Setxattr(path, name, data, 0); err != nil {
return &XAttrError{"setxattr", path, name, err} return &XAttrError{"setxattr", path, name, err}
@ -45,7 +51,8 @@ func Setxattr(path, name string, data []byte) error {
return nil return nil
} }
// Remove the attribute. // Removexattr removes the attribute associated
// with the given path.
func Removexattr(path, name string) error { func Removexattr(path, name string) error {
if err := syscall.Removexattr(path, name); err != nil { if err := syscall.Removexattr(path, name); err != nil {
return &XAttrError{"removexattr", path, name, err} return &XAttrError{"removexattr", path, name, err}