forked from AlekSi/xattr
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsyscall_darwin.go
156 lines (129 loc) · 3.33 KB
/
syscall_darwin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package xattr
import (
"syscall"
"unsafe"
)
func get(path, attr string, buf []byte) (rs int, err error) {
return getxattr(path, attr, buf, 0, 0)
}
// getxattr retrieves value of the extended attribute identified by attr
// associated with given path in filesystem into buffer buf.
//
// options specify options for retrieving extended attributes:
// - syscall.XATTR_NOFOLLOW
// - syscall.XATTR_SHOWCOMPRESSION
//
// position should be zero. For advanded usage see getxattr(2).
//
// On success, buf contains data associated with attr, retrieved value size sz
// and nil error returned.
//
// On error, non-nil error returned. It returns error if buf was to small.
//
// A nil slice can be passed as buf to get current size of attribute value,
// which can be used to estimate buf length for value associated with attr.
//
// See getxattr(2) for more details.
//
// ssize_t getxattr(const char *path, const char *name, void *value, size_t size, u_int32_t position, int options);
func getxattr(path, name string, buf []byte, position, options int) (sz int, err error) {
p, err := syscall.BytePtrFromString(path)
if err != nil {
return
}
n, err := syscall.BytePtrFromString(name)
if err != nil {
return
}
var b *byte
if len(buf) > 0 {
b = &buf[0]
}
r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR,
uintptr(unsafe.Pointer(p)),
uintptr(unsafe.Pointer(n)),
uintptr(unsafe.Pointer(b)),
uintptr(len(buf)),
uintptr(position),
uintptr(options))
sz = int(r0)
if e1 != 0 {
err = e1
}
return
}
func list(path string, dest []byte) (sz int, err error) {
return listxattr(path, dest, 0)
}
// ssize_t listxattr(const char *path, char *namebuf, size_t size, int options);
func listxattr(path string, buf []byte, options int) (sz int, err error) {
p, err := syscall.BytePtrFromString(path)
if err != nil {
return
}
var b *byte
if len(buf) > 0 {
b = &buf[0]
}
r0, _, e1 := syscall.Syscall6(syscall.SYS_LISTXATTR,
uintptr(unsafe.Pointer(p)),
uintptr(unsafe.Pointer(b)),
uintptr(len(buf)),
uintptr(options), 0, 0)
sz = int(r0)
if e1 != 0 {
err = e1
}
return
}
func set(path, attr string, data []byte, flags int) error {
return setxattr(path, attr, data, 0, flags)
}
// int setxattr(const char *path, const char *name, void *value, size_t size, u_int32_t position, int options);
func setxattr(path string, name string, data []byte, position, options int) (err error) {
p, err := syscall.BytePtrFromString(path)
if err != nil {
return
}
n, err := syscall.BytePtrFromString(name)
if err != nil {
return
}
var b *byte
if len(data) > 0 {
b = &data[0]
}
_, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR,
uintptr(unsafe.Pointer(p)),
uintptr(unsafe.Pointer(n)),
uintptr(unsafe.Pointer(b)),
uintptr(len(data)),
uintptr(position),
uintptr(options))
if e1 != 0 {
err = e1
}
return
}
func remove(path, attr string) error {
return removexattr(path, attr, 0)
}
// int removexattr(const char *path, const char *name, int options);
func removexattr(path string, name string, options int) (err error) {
p, err := syscall.BytePtrFromString(path)
if err != nil {
return
}
n, err := syscall.BytePtrFromString(name)
if err != nil {
return
}
_, _, e1 := syscall.Syscall(syscall.SYS_REMOVEXATTR,
uintptr(unsafe.Pointer(p)),
uintptr(unsafe.Pointer(n)),
uintptr(options))
if e1 != 0 {
err = e1
}
return
}