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 RenamexNp(from string, to string, flag uint32) (err error) {
408 return renamexNp(from, to, flag)
409 }
410
411
412
413 func RenameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) {
414 return renameatxNp(fromfd, from, tofd, to, flag)
415 }
416
417
418
419 func Uname(uname *Utsname) error {
420 mib := []_C_int{CTL_KERN, KERN_OSTYPE}
421 n := unsafe.Sizeof(uname.Sysname)
422 if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
423 return err
424 }
425
426 mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
427 n = unsafe.Sizeof(uname.Nodename)
428 if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
429 return err
430 }
431
432 mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
433 n = unsafe.Sizeof(uname.Release)
434 if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
435 return err
436 }
437
438 mib = []_C_int{CTL_KERN, KERN_VERSION}
439 n = unsafe.Sizeof(uname.Version)
440 if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
441 return err
442 }
443
444
445
446 for i, b := range uname.Version {
447 if b == '\n' || b == '\t' {
448 if i == len(uname.Version)-1 {
449 uname.Version[i] = 0
450 } else {
451 uname.Version[i] = ' '
452 }
453 }
454 }
455
456 mib = []_C_int{CTL_HW, HW_MACHINE}
457 n = unsafe.Sizeof(uname.Machine)
458 if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
459 return err
460 }
461
462 return nil
463 }
464
465 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
466 if raceenabled {
467 raceReleaseMerge(unsafe.Pointer(&ioSync))
468 }
469 var length = int64(count)
470 err = sendfile(infd, outfd, *offset, &length, nil, 0)
471 written = int(length)
472 return
473 }
474
475 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
476 var value IPMreqn
477 vallen := _Socklen(SizeofIPMreqn)
478 errno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
479 return &value, errno
480 }
481
482 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
483 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
484 }
485
486
487
488 func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
489 x := new(Xucred)
490 vallen := _Socklen(SizeofXucred)
491 err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
492 return x, err
493 }
494
495 func GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) {
496 var value TCPConnectionInfo
497 vallen := _Socklen(SizeofTCPConnectionInfo)
498 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
499 return &value, err
500 }
501
502 func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
503 mib, err := sysctlmib(name, args...)
504 if err != nil {
505 return nil, err
506 }
507
508 var kinfo KinfoProc
509 n := uintptr(SizeofKinfoProc)
510 if err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil {
511 return nil, err
512 }
513 if n != SizeofKinfoProc {
514 return nil, EIO
515 }
516 return &kinfo, nil
517 }
518
519 func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
520 mib, err := sysctlmib(name, args...)
521 if err != nil {
522 return nil, err
523 }
524
525 for {
526
527 n := uintptr(0)
528 if err := sysctl(mib, nil, &n, nil, 0); err != nil {
529 return nil, err
530 }
531 if n == 0 {
532 return nil, nil
533 }
534 if n%SizeofKinfoProc != 0 {
535 return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
536 }
537
538
539 buf := make([]KinfoProc, n/SizeofKinfoProc)
540 if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
541 if err == ENOMEM {
542
543 continue
544 }
545 return nil, err
546 }
547 if n%SizeofKinfoProc != 0 {
548 return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
549 }
550
551
552
553 return buf[:n/SizeofKinfoProc], nil
554 }
555 }
556
557
558
559 func PthreadChdir(path string) (err error) {
560 return pthread_chdir_np(path)
561 }
562
563
564
565 func PthreadFchdir(fd int) (err error) {
566 return pthread_fchdir_np(fd)
567 }
568
569
570
571
572
573
574
575
576
577
578 func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocID, flags uint32, iov []Iovec, connid *SaeConnID) (n uintptr, err error) {
579 endpoints := SaEndpoints{
580 Srcif: srcIf,
581 }
582
583 if srcAddr != nil {
584 addrp, addrlen, err := srcAddr.sockaddr()
585 if err != nil {
586 return 0, err
587 }
588 endpoints.Srcaddr = (*RawSockaddr)(addrp)
589 endpoints.Srcaddrlen = uint32(addrlen)
590 }
591
592 if dstAddr != nil {
593 addrp, addrlen, err := dstAddr.sockaddr()
594 if err != nil {
595 return 0, err
596 }
597 endpoints.Dstaddr = (*RawSockaddr)(addrp)
598 endpoints.Dstaddrlen = uint32(addrlen)
599 }
600
601 err = connectx(fd, &endpoints, associd, flags, iov, &n, connid)
602 return
603 }
604
605 const minIovec = 8
606
607 func Readv(fd int, iovs [][]byte) (n int, err error) {
608 iovecs := make([]Iovec, 0, minIovec)
609 iovecs = appendBytes(iovecs, iovs)
610 n, err = readv(fd, iovecs)
611 readvRacedetect(iovecs, n, err)
612 return n, err
613 }
614
615 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
616 iovecs := make([]Iovec, 0, minIovec)
617 iovecs = appendBytes(iovecs, iovs)
618 n, err = preadv(fd, iovecs, offset)
619 readvRacedetect(iovecs, n, err)
620 return n, err
621 }
622
623 func Writev(fd int, iovs [][]byte) (n int, err error) {
624 iovecs := make([]Iovec, 0, minIovec)
625 iovecs = appendBytes(iovecs, iovs)
626 if raceenabled {
627 raceReleaseMerge(unsafe.Pointer(&ioSync))
628 }
629 n, err = writev(fd, iovecs)
630 writevRacedetect(iovecs, n)
631 return n, err
632 }
633
634 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
635 iovecs := make([]Iovec, 0, minIovec)
636 iovecs = appendBytes(iovecs, iovs)
637 if raceenabled {
638 raceReleaseMerge(unsafe.Pointer(&ioSync))
639 }
640 n, err = pwritev(fd, iovecs, offset)
641 writevRacedetect(iovecs, n)
642 return n, err
643 }
644
645 func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
646 for _, b := range bs {
647 var v Iovec
648 v.SetLen(len(b))
649 if len(b) > 0 {
650 v.Base = &b[0]
651 } else {
652 v.Base = (*byte)(unsafe.Pointer(&_zero))
653 }
654 vecs = append(vecs, v)
655 }
656 return vecs
657 }
658
659 func writevRacedetect(iovecs []Iovec, n int) {
660 if !raceenabled {
661 return
662 }
663 for i := 0; n > 0 && i < len(iovecs); i++ {
664 m := int(iovecs[i].Len)
665 if m > n {
666 m = n
667 }
668 n -= m
669 if m > 0 {
670 raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
671 }
672 }
673 }
674
675 func readvRacedetect(iovecs []Iovec, n int, err error) {
676 if !raceenabled {
677 return
678 }
679 for i := 0; n > 0 && i < len(iovecs); i++ {
680 m := int(iovecs[i].Len)
681 if m > n {
682 m = n
683 }
684 n -= m
685 if m > 0 {
686 raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
687 }
688 }
689 if err == nil {
690 raceAcquire(unsafe.Pointer(&ioSync))
691 }
692 }
693
694
695
696
697
698
699
700
701
702
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
View as plain text