1
2
3
4
5
6
7
8
9
10
11
12
13 package unix
14
15 import (
16 "fmt"
17 "syscall"
18 "unsafe"
19 )
20
21
22
23
24 func fdopendir(fd int) (dir uintptr, err error) {
25 r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
26 dir = uintptr(r0)
27 if e1 != 0 {
28 err = errnoErr(e1)
29 }
30 return
31 }
32
33 var libc_fdopendir_trampoline_addr uintptr
34
35
36
37 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
38
39
40
41
42
43
44
45 skip, err := Seek(fd, 0, 1 )
46 if err != nil {
47 return 0, err
48 }
49
50
51
52
53
54
55
56 fd2, err := Openat(fd, ".", O_RDONLY, 0)
57 if err != nil {
58 return 0, err
59 }
60 d, err := fdopendir(fd2)
61 if err != nil {
62 Close(fd2)
63 return 0, err
64 }
65 defer closedir(d)
66
67 var cnt int64
68 for {
69 var entry Dirent
70 var entryp *Dirent
71 e := readdir_r(d, &entry, &entryp)
72 if e != 0 {
73 return n, errnoErr(e)
74 }
75 if entryp == nil {
76 break
77 }
78 if skip > 0 {
79 skip--
80 cnt++
81 continue
82 }
83
84 reclen := int(entry.Reclen)
85 if reclen > len(buf) {
86
87
88
89
90 break
91 }
92
93
94 s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
95 copy(buf, s)
96
97 buf = buf[reclen:]
98 n += reclen
99 cnt++
100 }
101
102
103 _, err = Seek(fd, cnt, 0 )
104 if err != nil {
105 return n, err
106 }
107
108 return n, nil
109 }
110
111
112 type SockaddrDatalink struct {
113 Len uint8
114 Family uint8
115 Index uint16
116 Type uint8
117 Nlen uint8
118 Alen uint8
119 Slen uint8
120 Data [12]int8
121 raw RawSockaddrDatalink
122 }
123
124
125 type SockaddrCtl struct {
126 ID uint32
127 Unit uint32
128 raw RawSockaddrCtl
129 }
130
131 func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
132 sa.raw.Sc_len = SizeofSockaddrCtl
133 sa.raw.Sc_family = AF_SYSTEM
134 sa.raw.Ss_sysaddr = AF_SYS_CONTROL
135 sa.raw.Sc_id = sa.ID
136 sa.raw.Sc_unit = sa.Unit
137 return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
138 }
139
140
141
142
143
144 type SockaddrVM struct {
145
146
147
148
149
150 CID uint32
151 Port uint32
152 raw RawSockaddrVM
153 }
154
155 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
156 sa.raw.Len = SizeofSockaddrVM
157 sa.raw.Family = AF_VSOCK
158 sa.raw.Port = sa.Port
159 sa.raw.Cid = sa.CID
160
161 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
162 }
163
164 func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
165 switch rsa.Addr.Family {
166 case AF_SYSTEM:
167 pp := (*RawSockaddrCtl)(unsafe.Pointer(rsa))
168 if pp.Ss_sysaddr == AF_SYS_CONTROL {
169 sa := new(SockaddrCtl)
170 sa.ID = pp.Sc_id
171 sa.Unit = pp.Sc_unit
172 return sa, nil
173 }
174 case AF_VSOCK:
175 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
176 sa := &SockaddrVM{
177 CID: pp.Cid,
178 Port: pp.Port,
179 }
180 return sa, nil
181 }
182 return nil, EAFNOSUPPORT
183 }
184
185
186
187
188 const SYS___SYSCTL = SYS_SYSCTL
189
190
191 func nametomib(name string) (mib []_C_int, err error) {
192 const siz = unsafe.Sizeof(mib[0])
193
194
195
196
197
198
199
200
201 var buf [CTL_MAXNAME + 2]_C_int
202 n := uintptr(CTL_MAXNAME) * siz
203
204 p := (*byte)(unsafe.Pointer(&buf[0]))
205 bytes, err := ByteSliceFromString(name)
206 if err != nil {
207 return nil, err
208 }
209
210
211
212 if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
213 return nil, err
214 }
215 return buf[0 : n/siz], nil
216 }
217
218 func direntIno(buf []byte) (uint64, bool) {
219 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
220 }
221
222 func direntReclen(buf []byte) (uint64, bool) {
223 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
224 }
225
226 func direntNamlen(buf []byte) (uint64, bool) {
227 return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
228 }
229
230 func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
231 func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
232 func PtraceDenyAttach() (err error) { return ptrace(PT_DENY_ATTACH, 0, 0, 0) }
233
234
235
236 func Pipe(p []int) (err error) {
237 if len(p) != 2 {
238 return EINVAL
239 }
240 var x [2]int32
241 err = pipe(&x)
242 if err == nil {
243 p[0] = int(x[0])
244 p[1] = int(x[1])
245 }
246 return
247 }
248
249 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
250 var _p0 unsafe.Pointer
251 var bufsize uintptr
252 if len(buf) > 0 {
253 _p0 = unsafe.Pointer(&buf[0])
254 bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
255 }
256 return getfsstat(_p0, bufsize, flags)
257 }
258
259 func xattrPointer(dest []byte) *byte {
260
261
262
263
264
265 var destp *byte
266 if len(dest) > 0 {
267 destp = &dest[0]
268 }
269 return destp
270 }
271
272
273
274 func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
275 return getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0)
276 }
277
278 func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
279 return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW)
280 }
281
282
283
284 func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
285 return fgetxattr(fd, attr, xattrPointer(dest), len(dest), 0, 0)
286 }
287
288
289
290 func Setxattr(path string, attr string, data []byte, flags int) (err error) {
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 return setxattr(path, attr, xattrPointer(data), len(data), 0, flags)
318 }
319
320 func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
321 return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)
322 }
323
324
325
326 func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
327 return fsetxattr(fd, attr, xattrPointer(data), len(data), 0, 0)
328 }
329
330
331
332 func Removexattr(path string, attr string) (err error) {
333
334
335
336 return removexattr(path, attr, 0)
337 }
338
339 func Lremovexattr(link string, attr string) (err error) {
340 return removexattr(link, attr, XATTR_NOFOLLOW)
341 }
342
343
344
345 func Fremovexattr(fd int, attr string) (err error) {
346 return fremovexattr(fd, attr, 0)
347 }
348
349
350
351 func Listxattr(path string, dest []byte) (sz int, err error) {
352 return listxattr(path, xattrPointer(dest), len(dest), 0)
353 }
354
355 func Llistxattr(link string, dest []byte) (sz int, err error) {
356 return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)
357 }
358
359
360
361 func Flistxattr(fd int, dest []byte) (sz int, err error) {
362 return flistxattr(fd, xattrPointer(dest), len(dest), 0)
363 }
364
365
366
367
370
371
372
373
374
375 func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
376
377
378
379
380 func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error {
381 return ioctlPtr(fd, CTLIOCGINFO, unsafe.Pointer(ctlInfo))
382 }
383
384
385 type IfreqMTU struct {
386 Name [IFNAMSIZ]byte
387 MTU int32
388 }
389
390
391
392 func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) {
393 var ifreq IfreqMTU
394 copy(ifreq.Name[:], ifname)
395 err := ioctlPtr(fd, SIOCGIFMTU, unsafe.Pointer(&ifreq))
396 return &ifreq, err
397 }
398
399
400
401 func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error {
402 return ioctlPtr(fd, SIOCSIFMTU, unsafe.Pointer(ifreq))
403 }
404
405
406
407 func Uname(uname *Utsname) error {
408 mib := []_C_int{CTL_KERN, KERN_OSTYPE}
409 n := unsafe.Sizeof(uname.Sysname)
410 if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
411 return err
412 }
413
414 mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
415 n = unsafe.Sizeof(uname.Nodename)
416 if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
417 return err
418 }
419
420 mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
421 n = unsafe.Sizeof(uname.Release)
422 if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
423 return err
424 }
425
426 mib = []_C_int{CTL_KERN, KERN_VERSION}
427 n = unsafe.Sizeof(uname.Version)
428 if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
429 return err
430 }
431
432
433
434 for i, b := range uname.Version {
435 if b == '\n' || b == '\t' {
436 if i == len(uname.Version)-1 {
437 uname.Version[i] = 0
438 } else {
439 uname.Version[i] = ' '
440 }
441 }
442 }
443
444 mib = []_C_int{CTL_HW, HW_MACHINE}
445 n = unsafe.Sizeof(uname.Machine)
446 if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
447 return err
448 }
449
450 return nil
451 }
452
453 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
454 if raceenabled {
455 raceReleaseMerge(unsafe.Pointer(&ioSync))
456 }
457 var length = int64(count)
458 err = sendfile(infd, outfd, *offset, &length, nil, 0)
459 written = int(length)
460 return
461 }
462
463 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
464 var value IPMreqn
465 vallen := _Socklen(SizeofIPMreqn)
466 errno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
467 return &value, errno
468 }
469
470 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
471 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
472 }
473
474
475
476 func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
477 x := new(Xucred)
478 vallen := _Socklen(SizeofXucred)
479 err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
480 return x, err
481 }
482
483 func GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) {
484 var value TCPConnectionInfo
485 vallen := _Socklen(SizeofTCPConnectionInfo)
486 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
487 return &value, err
488 }
489
490 func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
491 mib, err := sysctlmib(name, args...)
492 if err != nil {
493 return nil, err
494 }
495
496 var kinfo KinfoProc
497 n := uintptr(SizeofKinfoProc)
498 if err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil {
499 return nil, err
500 }
501 if n != SizeofKinfoProc {
502 return nil, EIO
503 }
504 return &kinfo, nil
505 }
506
507 func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
508 mib, err := sysctlmib(name, args...)
509 if err != nil {
510 return nil, err
511 }
512
513 for {
514
515 n := uintptr(0)
516 if err := sysctl(mib, nil, &n, nil, 0); err != nil {
517 return nil, err
518 }
519 if n == 0 {
520 return nil, nil
521 }
522 if n%SizeofKinfoProc != 0 {
523 return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
524 }
525
526
527 buf := make([]KinfoProc, n/SizeofKinfoProc)
528 if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
529 if err == ENOMEM {
530
531 continue
532 }
533 return nil, err
534 }
535 if n%SizeofKinfoProc != 0 {
536 return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
537 }
538
539
540
541 return buf[:n/SizeofKinfoProc], nil
542 }
543 }
544
545
546
547 func PthreadChdir(path string) (err error) {
548 return pthread_chdir_np(path)
549 }
550
551
552
553 func PthreadFchdir(fd int) (err error) {
554 return pthread_fchdir_np(fd)
555 }
556
557
558
559
560
561
562
563
564
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
View as plain text