xattrs_linux.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package system // import "github.com/docker/docker/pkg/system"
  2. import (
  3. "io/fs"
  4. "golang.org/x/sys/unix"
  5. )
  6. // Lgetxattr retrieves the value of the extended attribute identified by attr
  7. // and associated with the given path in the file system.
  8. // It will returns a nil slice and nil error if the xattr is not set.
  9. func Lgetxattr(path string, attr string) ([]byte, error) {
  10. pathErr := func(err error) ([]byte, error) {
  11. return nil, &fs.PathError{Op: "lgetxattr", Path: path, Err: err}
  12. }
  13. // Start with a 128 length byte array
  14. dest := make([]byte, 128)
  15. sz, errno := unix.Lgetxattr(path, attr, dest)
  16. for errno == unix.ERANGE {
  17. // Buffer too small, use zero-sized buffer to get the actual size
  18. sz, errno = unix.Lgetxattr(path, attr, []byte{})
  19. if errno != nil {
  20. return pathErr(errno)
  21. }
  22. dest = make([]byte, sz)
  23. sz, errno = unix.Lgetxattr(path, attr, dest)
  24. }
  25. switch {
  26. case errno == unix.ENODATA:
  27. return nil, nil
  28. case errno != nil:
  29. return pathErr(errno)
  30. }
  31. return dest[:sz], nil
  32. }
  33. // Lsetxattr sets the value of the extended attribute identified by attr
  34. // and associated with the given path in the file system.
  35. func Lsetxattr(path string, attr string, data []byte, flags int) error {
  36. err := unix.Lsetxattr(path, attr, data, flags)
  37. if err != nil {
  38. return &fs.PathError{Op: "lsetxattr", Path: path, Err: err}
  39. }
  40. return nil
  41. }