1
2
3
4
5
6
7
8
9
10
11
12
13 package unix
14
15 import (
16 "sync"
17 "unsafe"
18 )
19
20 const (
21 SYS_FSTAT_FREEBSD12 = 551
22 SYS_FSTATAT_FREEBSD12 = 552
23 SYS_GETDIRENTRIES_FREEBSD12 = 554
24 SYS_STATFS_FREEBSD12 = 555
25 SYS_FSTATFS_FREEBSD12 = 556
26 SYS_GETFSSTAT_FREEBSD12 = 557
27 SYS_MKNODAT_FREEBSD12 = 559
28 )
29
30
31 var (
32 osreldateOnce sync.Once
33 osreldate uint32
34 )
35
36
37 const _ino64First = 1200031
38
39 func supportsABI(ver uint32) bool {
40 osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") })
41 return osreldate >= ver
42 }
43
44
45 type SockaddrDatalink struct {
46 Len uint8
47 Family uint8
48 Index uint16
49 Type uint8
50 Nlen uint8
51 Alen uint8
52 Slen uint8
53 Data [46]int8
54 raw RawSockaddrDatalink
55 }
56
57 func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
58 return nil, EAFNOSUPPORT
59 }
60
61
62 func nametomib(name string) (mib []_C_int, err error) {
63 const siz = unsafe.Sizeof(mib[0])
64
65
66
67
68
69
70
71
72 var buf [CTL_MAXNAME + 2]_C_int
73 n := uintptr(CTL_MAXNAME) * siz
74
75 p := (*byte)(unsafe.Pointer(&buf[0]))
76 bytes, err := ByteSliceFromString(name)
77 if err != nil {
78 return nil, err
79 }
80
81
82
83 if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
84 return nil, err
85 }
86 return buf[0 : n/siz], nil
87 }
88
89 func direntIno(buf []byte) (uint64, bool) {
90 return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
91 }
92
93 func direntReclen(buf []byte) (uint64, bool) {
94 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
95 }
96
97 func direntNamlen(buf []byte) (uint64, bool) {
98 return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
99 }
100
101 func Pipe(p []int) (err error) {
102 return Pipe2(p, 0)
103 }
104
105
106
107 func Pipe2(p []int, flags int) error {
108 if len(p) != 2 {
109 return EINVAL
110 }
111 var pp [2]_C_int
112 err := pipe2(&pp, flags)
113 p[0] = int(pp[0])
114 p[1] = int(pp[1])
115 return err
116 }
117
118 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
119 var value IPMreqn
120 vallen := _Socklen(SizeofIPMreqn)
121 errno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
122 return &value, errno
123 }
124
125 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
126 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
127 }
128
129
130
131 func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
132 x := new(Xucred)
133 vallen := _Socklen(SizeofXucred)
134 err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
135 return x, err
136 }
137
138 func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
139 var rsa RawSockaddrAny
140 var len _Socklen = SizeofSockaddrAny
141 nfd, err = accept4(fd, &rsa, &len, flags)
142 if err != nil {
143 return
144 }
145 if len > SizeofSockaddrAny {
146 panic("RawSockaddrAny too small")
147 }
148 sa, err = anyToSockaddr(fd, &rsa)
149 if err != nil {
150 Close(nfd)
151 nfd = 0
152 }
153 return
154 }
155
156
157
158 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
159 var (
160 _p0 unsafe.Pointer
161 bufsize uintptr
162 oldBuf []statfs_freebsd11_t
163 needsConvert bool
164 )
165
166 if len(buf) > 0 {
167 if supportsABI(_ino64First) {
168 _p0 = unsafe.Pointer(&buf[0])
169 bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
170 } else {
171 n := len(buf)
172 oldBuf = make([]statfs_freebsd11_t, n)
173 _p0 = unsafe.Pointer(&oldBuf[0])
174 bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n)
175 needsConvert = true
176 }
177 }
178 var sysno uintptr = SYS_GETFSSTAT
179 if supportsABI(_ino64First) {
180 sysno = SYS_GETFSSTAT_FREEBSD12
181 }
182 r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags))
183 n = int(r0)
184 if e1 != 0 {
185 err = e1
186 }
187 if e1 == 0 && needsConvert {
188 for i := range oldBuf {
189 buf[i].convertFrom(&oldBuf[i])
190 }
191 }
192 return
193 }
194
195 func setattrlistTimes(path string, times []Timespec, flags int) error {
196
197 return ENOSYS
198 }
199
200
201
202
203
204 func Uname(uname *Utsname) error {
205 mib := []_C_int{CTL_KERN, KERN_OSTYPE}
206 n := unsafe.Sizeof(uname.Sysname)
207 if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
208 return err
209 }
210
211 mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
212 n = unsafe.Sizeof(uname.Nodename)
213 if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
214 return err
215 }
216
217 mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
218 n = unsafe.Sizeof(uname.Release)
219 if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
220 return err
221 }
222
223 mib = []_C_int{CTL_KERN, KERN_VERSION}
224 n = unsafe.Sizeof(uname.Version)
225 if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
226 return err
227 }
228
229
230
231 for i, b := range uname.Version {
232 if b == '\n' || b == '\t' {
233 if i == len(uname.Version)-1 {
234 uname.Version[i] = 0
235 } else {
236 uname.Version[i] = ' '
237 }
238 }
239 }
240
241 mib = []_C_int{CTL_HW, HW_MACHINE}
242 n = unsafe.Sizeof(uname.Machine)
243 if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
244 return err
245 }
246
247 return nil
248 }
249
250 func Stat(path string, st *Stat_t) (err error) {
251 var oldStat stat_freebsd11_t
252 if supportsABI(_ino64First) {
253 return fstatat_freebsd12(AT_FDCWD, path, st, 0)
254 }
255 err = stat(path, &oldStat)
256 if err != nil {
257 return err
258 }
259
260 st.convertFrom(&oldStat)
261 return nil
262 }
263
264 func Lstat(path string, st *Stat_t) (err error) {
265 var oldStat stat_freebsd11_t
266 if supportsABI(_ino64First) {
267 return fstatat_freebsd12(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
268 }
269 err = lstat(path, &oldStat)
270 if err != nil {
271 return err
272 }
273
274 st.convertFrom(&oldStat)
275 return nil
276 }
277
278 func Fstat(fd int, st *Stat_t) (err error) {
279 var oldStat stat_freebsd11_t
280 if supportsABI(_ino64First) {
281 return fstat_freebsd12(fd, st)
282 }
283 err = fstat(fd, &oldStat)
284 if err != nil {
285 return err
286 }
287
288 st.convertFrom(&oldStat)
289 return nil
290 }
291
292 func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) {
293 var oldStat stat_freebsd11_t
294 if supportsABI(_ino64First) {
295 return fstatat_freebsd12(fd, path, st, flags)
296 }
297 err = fstatat(fd, path, &oldStat, flags)
298 if err != nil {
299 return err
300 }
301
302 st.convertFrom(&oldStat)
303 return nil
304 }
305
306 func Statfs(path string, st *Statfs_t) (err error) {
307 var oldStatfs statfs_freebsd11_t
308 if supportsABI(_ino64First) {
309 return statfs_freebsd12(path, st)
310 }
311 err = statfs(path, &oldStatfs)
312 if err != nil {
313 return err
314 }
315
316 st.convertFrom(&oldStatfs)
317 return nil
318 }
319
320 func Fstatfs(fd int, st *Statfs_t) (err error) {
321 var oldStatfs statfs_freebsd11_t
322 if supportsABI(_ino64First) {
323 return fstatfs_freebsd12(fd, st)
324 }
325 err = fstatfs(fd, &oldStatfs)
326 if err != nil {
327 return err
328 }
329
330 st.convertFrom(&oldStatfs)
331 return nil
332 }
333
334 func Getdents(fd int, buf []byte) (n int, err error) {
335 return Getdirentries(fd, buf, nil)
336 }
337
338 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
339 if supportsABI(_ino64First) {
340 if basep == nil || unsafe.Sizeof(*basep) == 8 {
341 return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep)))
342 }
343
344
345 var base uint64 = uint64(*basep)
346 n, err = getdirentries_freebsd12(fd, buf, &base)
347 *basep = uintptr(base)
348 if base>>32 != 0 {
349
350
351
352 err = EIO
353 }
354 return
355 }
356
357
358
359 oldBufLen := roundup(len(buf)/4, _dirblksiz)
360 oldBuf := make([]byte, oldBufLen)
361 n, err = getdirentries(fd, oldBuf, basep)
362 if err == nil && n > 0 {
363 n = convertFromDirents11(buf, oldBuf[:n])
364 }
365 return
366 }
367
368 func Mknod(path string, mode uint32, dev uint64) (err error) {
369 var oldDev int
370 if supportsABI(_ino64First) {
371 return mknodat_freebsd12(AT_FDCWD, path, mode, dev)
372 }
373 oldDev = int(dev)
374 return mknod(path, mode, oldDev)
375 }
376
377 func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
378 var oldDev int
379 if supportsABI(_ino64First) {
380 return mknodat_freebsd12(fd, path, mode, dev)
381 }
382 oldDev = int(dev)
383 return mknodat(fd, path, mode, oldDev)
384 }
385
386
387
388
389
390 func roundup(x, y int) int {
391 return ((x + y - 1) / y) * y
392 }
393
394 func (s *Stat_t) convertFrom(old *stat_freebsd11_t) {
395 *s = Stat_t{
396 Dev: uint64(old.Dev),
397 Ino: uint64(old.Ino),
398 Nlink: uint64(old.Nlink),
399 Mode: old.Mode,
400 Uid: old.Uid,
401 Gid: old.Gid,
402 Rdev: uint64(old.Rdev),
403 Atim: old.Atim,
404 Mtim: old.Mtim,
405 Ctim: old.Ctim,
406 Btim: old.Btim,
407 Size: old.Size,
408 Blocks: old.Blocks,
409 Blksize: old.Blksize,
410 Flags: old.Flags,
411 Gen: uint64(old.Gen),
412 }
413 }
414
415 func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) {
416 *s = Statfs_t{
417 Version: _statfsVersion,
418 Type: old.Type,
419 Flags: old.Flags,
420 Bsize: old.Bsize,
421 Iosize: old.Iosize,
422 Blocks: old.Blocks,
423 Bfree: old.Bfree,
424 Bavail: old.Bavail,
425 Files: old.Files,
426 Ffree: old.Ffree,
427 Syncwrites: old.Syncwrites,
428 Asyncwrites: old.Asyncwrites,
429 Syncreads: old.Syncreads,
430 Asyncreads: old.Asyncreads,
431
432 Namemax: old.Namemax,
433 Owner: old.Owner,
434 Fsid: old.Fsid,
435
436
437
438
439 }
440
441 sl := old.Fstypename[:]
442 n := clen(*(*[]byte)(unsafe.Pointer(&sl)))
443 copy(s.Fstypename[:], old.Fstypename[:n])
444
445 sl = old.Mntfromname[:]
446 n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
447 copy(s.Mntfromname[:], old.Mntfromname[:n])
448
449 sl = old.Mntonname[:]
450 n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
451 copy(s.Mntonname[:], old.Mntonname[:n])
452 }
453
454 func convertFromDirents11(buf []byte, old []byte) int {
455 const (
456 fixedSize = int(unsafe.Offsetof(Dirent{}.Name))
457 oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name))
458 )
459
460 dstPos := 0
461 srcPos := 0
462 for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) {
463 var dstDirent Dirent
464 var srcDirent dirent_freebsd11
465
466
467
468 copy((*[unsafe.Sizeof(srcDirent)]byte)(unsafe.Pointer(&srcDirent))[:], old[srcPos:])
469
470 reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8)
471 if dstPos+reclen > len(buf) {
472 break
473 }
474
475 dstDirent.Fileno = uint64(srcDirent.Fileno)
476 dstDirent.Off = 0
477 dstDirent.Reclen = uint16(reclen)
478 dstDirent.Type = srcDirent.Type
479 dstDirent.Pad0 = 0
480 dstDirent.Namlen = uint16(srcDirent.Namlen)
481 dstDirent.Pad1 = 0
482
483 copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen])
484 copy(buf[dstPos:], (*[unsafe.Sizeof(dstDirent)]byte)(unsafe.Pointer(&dstDirent))[:])
485 padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen]
486 for i := range padding {
487 padding[i] = 0
488 }
489
490 dstPos += int(dstDirent.Reclen)
491 srcPos += int(srcDirent.Reclen)
492 }
493
494 return dstPos
495 }
496
497 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
498 if raceenabled {
499 raceReleaseMerge(unsafe.Pointer(&ioSync))
500 }
501 return sendfile(outfd, infd, offset, count)
502 }
503
504
505
506 func PtraceAttach(pid int) (err error) {
507 return ptrace(PTRACE_ATTACH, pid, 0, 0)
508 }
509
510 func PtraceCont(pid int, signal int) (err error) {
511 return ptrace(PTRACE_CONT, pid, 1, signal)
512 }
513
514 func PtraceDetach(pid int) (err error) {
515 return ptrace(PTRACE_DETACH, pid, 1, 0)
516 }
517
518 func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) {
519 return ptrace(PTRACE_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0)
520 }
521
522 func PtraceGetRegs(pid int, regsout *Reg) (err error) {
523 return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0)
524 }
525
526 func PtraceLwpEvents(pid int, enable int) (err error) {
527 return ptrace(PTRACE_LWPEVENTS, pid, 0, enable)
528 }
529
530 func PtraceLwpInfo(pid int, info uintptr) (err error) {
531 return ptrace(PTRACE_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{})))
532 }
533
534 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
535 return PtraceIO(PIOD_READ_D, pid, addr, out, SizeofLong)
536 }
537
538 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
539 return PtraceIO(PIOD_READ_I, pid, addr, out, SizeofLong)
540 }
541
542 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
543 return PtraceIO(PIOD_WRITE_D, pid, addr, data, SizeofLong)
544 }
545
546 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
547 return PtraceIO(PIOD_WRITE_I, pid, addr, data, SizeofLong)
548 }
549
550 func PtraceSetRegs(pid int, regs *Reg) (err error) {
551 return ptrace(PTRACE_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0)
552 }
553
554 func PtraceSingleStep(pid int) (err error) {
555 return ptrace(PTRACE_SINGLESTEP, pid, 1, 0)
556 }
557
558
561
562
563
564
565
566
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
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
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
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
View as plain text