func FSet(f *os.File, name string, data []byte) error {
	if err := fsetxattr(f, name, data, 0); err != nil {
		return &Error{"xattr.FSet", f.Name(), name, err}
	}
	return nil
}
FSet is like Set but accepts a os.File instead of a file path.
package xattr
import (
	"os"
	"syscall"
)
type Error struct {
	Op   string
	Path string
	Name string
	Err  error
}
func (e *Error) Error() string {
	return e.Op + " " + e.Path + " " + e.Name + ": " + e.Err.Error()
}
func Get(path, name string) ([]byte, error) {
	return get(path, name, func(name string, data []byte) (int, error) {
		return getxattr(path, name, data)
	})
}
func LGet(path, name string) ([]byte, error) {
	return get(path, name, func(name string, data []byte) (int, error) {
		return lgetxattr(path, name, data)
	})
}
func FGet(f *os.File, name string) ([]byte, error) {
	return get(f.Name(), name, func(name string, data []byte) (int, error) {
		return fgetxattr(f, name, data)
	})
}
type getxattrFunc func(name string, data []byte) (int, error)
func get(path string, name string, getxattrFunc getxattrFunc) ([]byte, error) {
	const (
		initialBufSize = 1024
		maxBufSize = 64 * 1024 * 1024
		myname = "xattr.get"
	)
	size := initialBufSize
	for {
		data := make([]byte, size)
		read, err := getxattrFunc(name, data)
		if err == syscall.ERANGE || read == size {
			size <<= 1
			if size >= maxBufSize {
				return nil, &Error{myname, path, name, syscall.EOVERFLOW}
			}
			continue
		}
		if err != nil {
			return nil, &Error{myname, path, name, err}
		}
		return data[:read], nil
	}
}
func Set(path, name string, data []byte) error {
	if err := setxattr(path, name, data, 0); err != nil {
		return &Error{"xattr.Set", path, name, err}
	}
	return nil
}
func LSet(path, name string, data []byte) error {
	if err := lsetxattr(path, name, data, 0); err != nil {
		return &Error{"xattr.LSet", path, name, err}
	}
	return nil
}