xattrs_linux.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package system
  2. import (
  3. "syscall"
  4. "unsafe"
  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. pathBytes, err := syscall.BytePtrFromString(path)
  11. if err != nil {
  12. return nil, err
  13. }
  14. attrBytes, err := syscall.BytePtrFromString(attr)
  15. if err != nil {
  16. return nil, err
  17. }
  18. dest := make([]byte, 128)
  19. destBytes := unsafe.Pointer(&dest[0])
  20. sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
  21. if errno == syscall.ENODATA {
  22. return nil, nil
  23. }
  24. if errno == syscall.ERANGE {
  25. dest = make([]byte, sz)
  26. destBytes := unsafe.Pointer(&dest[0])
  27. sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
  28. }
  29. if errno != 0 {
  30. return nil, errno
  31. }
  32. return dest[:sz], nil
  33. }
  34. var _zero uintptr
  35. // Lsetxattr sets the value of the extended attribute identified by attr
  36. // and associated with the given path in the file system.
  37. func Lsetxattr(path string, attr string, data []byte, flags int) error {
  38. pathBytes, err := syscall.BytePtrFromString(path)
  39. if err != nil {
  40. return err
  41. }
  42. attrBytes, err := syscall.BytePtrFromString(attr)
  43. if err != nil {
  44. return err
  45. }
  46. var dataBytes unsafe.Pointer
  47. if len(data) > 0 {
  48. dataBytes = unsafe.Pointer(&data[0])
  49. } else {
  50. dataBytes = unsafe.Pointer(&_zero)
  51. }
  52. _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
  53. if errno != 0 {
  54. return errno
  55. }
  56. return nil
  57. }