From 3d478c1043434edf347e8758f9ed4085bc70e6eb Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 14 Feb 2014 14:24:37 +0100 Subject: [PATCH] Archive: Add Add Lgetxattr and Lsetxattr implementations Docker-DCO-1.1-Signed-off-by: Alexander Larsson (github: alexlarsson) Upstream-commit: d19e998e7a99d24122da3e98d9886e3b7b4b3501 Component: engine --- components/engine/archive/stat_linux.go | 53 +++++++++++++++++++ components/engine/archive/stat_unsupported.go | 8 +++ 2 files changed, 61 insertions(+) diff --git a/components/engine/archive/stat_linux.go b/components/engine/archive/stat_linux.go index f87a99c55a..2910ce5bab 100644 --- a/components/engine/archive/stat_linux.go +++ b/components/engine/archive/stat_linux.go @@ -37,3 +37,56 @@ func UtimesNano(path string, ts []syscall.Timespec) error { } return nil } + +// Returns a nil slice and nil error if the xattr is not set +func Lgetxattr(path string, attr string) ([]byte, error) { + pathBytes, err := syscall.BytePtrFromString(path) + if err != nil { + return nil, err + } + attrBytes, err := syscall.BytePtrFromString(attr) + if err != nil { + return nil, err + } + + dest := make([]byte, 128) + destBytes := unsafe.Pointer(&dest[0]) + sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) + if errno == syscall.ENODATA { + return nil, nil + } + if errno == syscall.ERANGE { + dest = make([]byte, sz) + destBytes := unsafe.Pointer(&dest[0]) + sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) + } + if errno != 0 { + return nil, errno + } + + return dest[:sz], nil +} + +var _zero uintptr + +func Lsetxattr(path string, attr string, data []byte, flags int) error { + pathBytes, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + attrBytes, err := syscall.BytePtrFromString(attr) + if err != nil { + return err + } + var dataBytes unsafe.Pointer + if len(data) > 0 { + dataBytes = unsafe.Pointer(&data[0]) + } else { + dataBytes = unsafe.Pointer(&_zero) + } + _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0) + if errno != 0 { + return errno + } + return nil +} diff --git a/components/engine/archive/stat_unsupported.go b/components/engine/archive/stat_unsupported.go index 50ca461867..99f1fbc7da 100644 --- a/components/engine/archive/stat_unsupported.go +++ b/components/engine/archive/stat_unsupported.go @@ -19,3 +19,11 @@ func LUtimesNano(path string, ts []syscall.Timespec) error { func UtimesNano(path string, ts []syscall.Timespec) error { return ErrNotImplemented } + +func Lgetxattr(path string, attr string) ([]byte, error) { + return nil, ErrNotImplemented +} + +func Lsetxattr(path string, attr string, data []byte, flags int) error { + return ErrNotImplemented +}