Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / opencontainers / selinux / go-selinux / xattrs.go
1 // +build linux
2
3 package selinux
4
5 import (
6         "syscall"
7         "unsafe"
8 )
9
10 var _zero uintptr
11
12 // Returns a []byte slice if the xattr is set and nil otherwise
13 // Requires path and its attribute as arguments
14 func lgetxattr(path string, attr string) ([]byte, error) {
15         var sz int
16         pathBytes, err := syscall.BytePtrFromString(path)
17         if err != nil {
18                 return nil, err
19         }
20         attrBytes, err := syscall.BytePtrFromString(attr)
21         if err != nil {
22                 return nil, err
23         }
24
25         // Start with a 128 length byte array
26         sz = 128
27         dest := make([]byte, sz)
28         destBytes := unsafe.Pointer(&dest[0])
29         _sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
30
31         switch {
32         case errno == syscall.ENODATA:
33                 return nil, errno
34         case errno == syscall.ENOTSUP:
35                 return nil, errno
36         case errno == syscall.ERANGE:
37                 // 128 byte array might just not be good enough,
38                 // A dummy buffer is used ``uintptr(0)`` to get real size
39                 // of the xattrs on disk
40                 _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0)
41                 sz = int(_sz)
42                 if sz < 0 {
43                         return nil, errno
44                 }
45                 dest = make([]byte, sz)
46                 destBytes := unsafe.Pointer(&dest[0])
47                 _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
48                 if errno != 0 {
49                         return nil, errno
50                 }
51         case errno != 0:
52                 return nil, errno
53         }
54         sz = int(_sz)
55         return dest[:sz], nil
56 }
57
58 func lsetxattr(path string, attr string, data []byte, flags int) error {
59         pathBytes, err := syscall.BytePtrFromString(path)
60         if err != nil {
61                 return err
62         }
63         attrBytes, err := syscall.BytePtrFromString(attr)
64         if err != nil {
65                 return err
66         }
67         var dataBytes unsafe.Pointer
68         if len(data) > 0 {
69                 dataBytes = unsafe.Pointer(&data[0])
70         } else {
71                 dataBytes = unsafe.Pointer(&_zero)
72         }
73         _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
74         if errno != 0 {
75                 return errno
76         }
77         return nil
78 }