github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/system/xattrs_linux.go (about) 1 package system 2 3 import ( 4 "syscall" 5 "unsafe" 6 ) 7 8 var _zero uintptr 9 10 // Returns the size of xattrs and nil error 11 // Requires path, takes allocated []byte or nil as last argument 12 func Llistxattr(path string, dest []byte) (size int, err error) { 13 pathBytes, err := syscall.BytePtrFromString(path) 14 if err != nil { 15 return -1, err 16 } 17 var newpathBytes unsafe.Pointer 18 if len(dest) > 0 { 19 newpathBytes = unsafe.Pointer(&dest[0]) 20 } else { 21 newpathBytes = unsafe.Pointer(&_zero) 22 } 23 24 _size, _, errno := syscall.Syscall6(syscall.SYS_LLISTXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(newpathBytes), uintptr(len(dest)), 0, 0, 0) 25 size = int(_size) 26 if errno != 0 { 27 return -1, errno 28 } 29 30 return size, nil 31 } 32 33 // Returns a []byte slice if the xattr is set and nil otherwise 34 // Requires path and its attribute as arguments 35 func Lgetxattr(path string, attr string) ([]byte, error) { 36 var sz int 37 pathBytes, err := syscall.BytePtrFromString(path) 38 if err != nil { 39 return nil, err 40 } 41 attrBytes, err := syscall.BytePtrFromString(attr) 42 if err != nil { 43 return nil, err 44 } 45 46 // Start with a 128 length byte array 47 sz = 128 48 dest := make([]byte, sz) 49 destBytes := unsafe.Pointer(&dest[0]) 50 _sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) 51 52 switch { 53 case errno == syscall.ENODATA: 54 return nil, errno 55 case errno == syscall.ENOTSUP: 56 return nil, errno 57 case errno == syscall.ERANGE: 58 // 128 byte array might just not be good enough, 59 // A dummy buffer is used ``uintptr(0)`` to get real size 60 // of the xattrs on disk 61 _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0) 62 sz = int(_sz) 63 if sz < 0 { 64 return nil, errno 65 } 66 dest = make([]byte, sz) 67 destBytes := unsafe.Pointer(&dest[0]) 68 _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) 69 if errno != 0 { 70 return nil, errno 71 } 72 case errno != 0: 73 return nil, errno 74 } 75 sz = int(_sz) 76 return dest[:sz], nil 77 } 78 79 func Lsetxattr(path string, attr string, data []byte, flags int) error { 80 pathBytes, err := syscall.BytePtrFromString(path) 81 if err != nil { 82 return err 83 } 84 attrBytes, err := syscall.BytePtrFromString(attr) 85 if err != nil { 86 return err 87 } 88 var dataBytes unsafe.Pointer 89 if len(data) > 0 { 90 dataBytes = unsafe.Pointer(&data[0]) 91 } else { 92 dataBytes = unsafe.Pointer(&_zero) 93 } 94 _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0) 95 if errno != 0 { 96 return errno 97 } 98 return nil 99 }