Source file src/syscall/syscall_darwin.go
1
2
3
4
5
6
7
8
9
10
11
12
13 package syscall
14
15 import (
16 errorspkg "errors"
17 "unsafe"
18 )
19
20 const ImplementsGetwd = true
21
22 func Getwd() (string, error) {
23 buf := make([]byte, 2048)
24 attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0)
25 if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 {
26 wd := string(attrs[0])
27
28
29 if wd[0] == '/' && wd[len(wd)-1] == 0 {
30 return wd[:len(wd)-1], nil
31 }
32 }
33
34
35 return "", ENOTSUP
36 }
37
38 type SockaddrDatalink struct {
39 Len uint8
40 Family uint8
41 Index uint16
42 Type uint8
43 Nlen uint8
44 Alen uint8
45 Slen uint8
46 Data [12]int8
47 raw RawSockaddrDatalink
48 }
49
50
51 func nametomib(name string) (mib []_C_int, err error) {
52 const siz = unsafe.Sizeof(mib[0])
53
54
55
56
57
58
59
60
61 var buf [CTL_MAXNAME + 2]_C_int
62 n := uintptr(CTL_MAXNAME) * siz
63
64 p := (*byte)(unsafe.Pointer(&buf[0]))
65 bytes, err := ByteSliceFromString(name)
66 if err != nil {
67 return nil, err
68 }
69
70
71
72 if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
73 return nil, err
74 }
75 return buf[0 : n/siz], nil
76 }
77
78 func direntIno(buf []byte) (uint64, bool) {
79 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
80 }
81
82 func direntReclen(buf []byte) (uint64, bool) {
83 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
84 }
85
86 func direntNamlen(buf []byte) (uint64, bool) {
87 return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
88 }
89
90 func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
91 func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
92
93 const (
94 attrBitMapCount = 5
95 attrCmnModtime = 0x00000400
96 attrCmnAcctime = 0x00001000
97 attrCmnFullpath = 0x08000000
98 )
99
100 type attrList struct {
101 bitmapCount uint16
102 _ uint16
103 CommonAttr uint32
104 VolAttr uint32
105 DirAttr uint32
106 FileAttr uint32
107 Forkattr uint32
108 }
109
110 func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
111 if len(attrBuf) < 4 {
112 return nil, errorspkg.New("attrBuf too small")
113 }
114 attrList.bitmapCount = attrBitMapCount
115
116 var _p0 *byte
117 _p0, err = BytePtrFromString(path)
118 if err != nil {
119 return nil, err
120 }
121
122 _, _, e1 := syscall6(
123 funcPC(libc_getattrlist_trampoline),
124 uintptr(unsafe.Pointer(_p0)),
125 uintptr(unsafe.Pointer(&attrList)),
126 uintptr(unsafe.Pointer(&attrBuf[0])),
127 uintptr(len(attrBuf)),
128 uintptr(options),
129 0,
130 )
131 if e1 != 0 {
132 return nil, e1
133 }
134 size := *(*uint32)(unsafe.Pointer(&attrBuf[0]))
135
136
137
138
139 dat := attrBuf
140 if int(size) < len(attrBuf) {
141 dat = dat[:size]
142 }
143 dat = dat[4:]
144
145 for i := uint32(0); int(i) < len(dat); {
146 header := dat[i:]
147 if len(header) < 8 {
148 return attrs, errorspkg.New("truncated attribute header")
149 }
150 datOff := *(*int32)(unsafe.Pointer(&header[0]))
151 attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
152 if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
153 return attrs, errorspkg.New("truncated results; attrBuf too small")
154 }
155 end := uint32(datOff) + attrLen
156 attrs = append(attrs, dat[datOff:end])
157 i = end
158 if r := i % 4; r != 0 {
159 i += (4 - r)
160 }
161 }
162 return
163 }
164
165 func libc_getattrlist_trampoline()
166
167
168
169
170
171
172 func Pipe(p []int) (err error) {
173 if len(p) != 2 {
174 return EINVAL
175 }
176 var q [2]int32
177 err = pipe(&q)
178 p[0] = int(q[0])
179 p[1] = int(q[1])
180 return
181 }
182
183 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
184 var _p0 unsafe.Pointer
185 var bufsize uintptr
186 if len(buf) > 0 {
187 _p0 = unsafe.Pointer(&buf[0])
188 bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
189 }
190 r0, _, e1 := syscall(funcPC(libc_getfsstat_trampoline), uintptr(_p0), bufsize, uintptr(flags))
191 n = int(r0)
192 if e1 != 0 {
193 err = e1
194 }
195 return
196 }
197
198 func libc_getfsstat_trampoline()
199
200
201
202
203 func setattrlistTimes(path string, times []Timespec) error {
204 _p0, err := BytePtrFromString(path)
205 if err != nil {
206 return err
207 }
208
209 var attrList attrList
210 attrList.bitmapCount = attrBitMapCount
211 attrList.CommonAttr = attrCmnModtime | attrCmnAcctime
212
213
214 attributes := [2]Timespec{times[1], times[0]}
215 const options = 0
216 _, _, e1 := syscall6(
217 funcPC(libc_setattrlist_trampoline),
218 uintptr(unsafe.Pointer(_p0)),
219 uintptr(unsafe.Pointer(&attrList)),
220 uintptr(unsafe.Pointer(&attributes)),
221 uintptr(unsafe.Sizeof(attributes)),
222 uintptr(options),
223 0,
224 )
225 if e1 != 0 {
226 return e1
227 }
228 return nil
229 }
230
231 func libc_setattrlist_trampoline()
232
233
234
235
236 func utimensat(dirfd int, path string, times *[2]Timespec, flag int) error {
237
238 return ENOSYS
239 }
240
241
244
245
246
247 func Kill(pid int, signum Signal) (err error) { return kill(pid, int(signum), 1) }
248
249
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345 func init() {
346 execveDarwin = execve
347 }
348
349 func fdopendir(fd int) (dir uintptr, err error) {
350 r0, _, e1 := syscallPtr(funcPC(libc_fdopendir_trampoline), uintptr(fd), 0, 0)
351 dir = uintptr(r0)
352 if e1 != 0 {
353 err = errnoErr(e1)
354 }
355 return
356 }
357
358 func libc_fdopendir_trampoline()
359
360
361
362
363 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
364 r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
365 n = int(r0)
366 if e1 != 0 {
367 err = errnoErr(e1)
368 }
369 return
370 }
371
372 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
373 r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
374 n = int(r0)
375 if e1 != 0 {
376 err = errnoErr(e1)
377 }
378 return
379 }
380
381 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
382
383 const ptrSize = unsafe.Sizeof(uintptr(0))
384
385
386
387
388
389
390
391 skip, err := Seek(fd, 0, 1 )
392 if err != nil {
393 return 0, err
394 }
395
396
397
398
399
400
401
402 fd2, err := openat(fd, ".", O_RDONLY, 0)
403 if err != nil {
404 return 0, err
405 }
406 d, err := fdopendir(fd2)
407 if err != nil {
408 Close(fd2)
409 return 0, err
410 }
411 defer closedir(d)
412
413 var cnt int64
414 for {
415 var entry Dirent
416 var entryp *Dirent
417 e := readdir_r(d, &entry, &entryp)
418 if e != 0 {
419 return n, errnoErr(e)
420 }
421 if entryp == nil {
422 break
423 }
424 if skip > 0 {
425 skip--
426 cnt++
427 continue
428 }
429 reclen := int(entry.Reclen)
430 if reclen > len(buf) {
431
432
433
434
435 break
436 }
437
438 s := struct {
439 ptr unsafe.Pointer
440 siz int
441 cap int
442 }{ptr: unsafe.Pointer(&entry), siz: reclen, cap: reclen}
443 copy(buf, *(*[]byte)(unsafe.Pointer(&s)))
444 buf = buf[reclen:]
445 n += reclen
446 cnt++
447 }
448
449
450 _, err = Seek(fd, cnt, 0 )
451 if err != nil {
452 return n, err
453 }
454
455 return n, nil
456 }
457
458
459 func syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
460 func syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
461 func syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
462 func rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
463 func rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
464 func syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
465
466
467
468
469 func funcPC(f func()) uintptr {
470 return **(**uintptr)(unsafe.Pointer(&f))
471 }
472
View as plain text