@@ -602,7 +602,150 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI
602
602
return
603
603
}
604
604
605
- //sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error)
605
+ // sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error)
606
+ const minIovec = 8
607
+
608
+ func Readv (fd int , iovs [][]byte ) (n int , err error ) {
609
+ if ! darwinKernelVersionMin (11 , 0 , 0 ) {
610
+ return 0 , ENOSYS
611
+ }
612
+
613
+ iovecs := make ([]Iovec , 0 , minIovec )
614
+ iovecs = appendBytes (iovecs , iovs )
615
+ n , err = readv (fd , iovecs )
616
+ readvRacedetect (iovecs , n , err )
617
+ return n , err
618
+ }
619
+
620
+ func Preadv (fd int , iovs [][]byte , offset int64 ) (n int , err error ) {
621
+ if ! darwinKernelVersionMin (11 , 0 , 0 ) {
622
+ return 0 , ENOSYS
623
+ }
624
+ iovecs := make ([]Iovec , 0 , minIovec )
625
+ iovecs = appendBytes (iovecs , iovs )
626
+ n , err = preadv (fd , iovecs , offset )
627
+ readvRacedetect (iovecs , n , err )
628
+ return n , err
629
+ }
630
+
631
+ func Writev (fd int , iovs [][]byte ) (n int , err error ) {
632
+ if ! darwinKernelVersionMin (11 , 0 , 0 ) {
633
+ return 0 , ENOSYS
634
+ }
635
+
636
+ iovecs := make ([]Iovec , 0 , minIovec )
637
+ iovecs = appendBytes (iovecs , iovs )
638
+ if raceenabled {
639
+ raceReleaseMerge (unsafe .Pointer (& ioSync ))
640
+ }
641
+ n , err = writev (fd , iovecs )
642
+ writevRacedetect (iovecs , n )
643
+ return n , err
644
+ }
645
+
646
+ func Pwritev (fd int , iovs [][]byte , offset int64 ) (n int , err error ) {
647
+ if ! darwinKernelVersionMin (11 , 0 , 0 ) {
648
+ return 0 , ENOSYS
649
+ }
650
+
651
+ iovecs := make ([]Iovec , 0 , minIovec )
652
+ iovecs = appendBytes (iovecs , iovs )
653
+ if raceenabled {
654
+ raceReleaseMerge (unsafe .Pointer (& ioSync ))
655
+ }
656
+ n , err = pwritev (fd , iovecs , offset )
657
+ writevRacedetect (iovecs , n )
658
+ return n , err
659
+ }
660
+
661
+ func appendBytes (vecs []Iovec , bs [][]byte ) []Iovec {
662
+ for _ , b := range bs {
663
+ var v Iovec
664
+ v .SetLen (len (b ))
665
+ if len (b ) > 0 {
666
+ v .Base = & b [0 ]
667
+ } else {
668
+ v .Base = (* byte )(unsafe .Pointer (& _zero ))
669
+ }
670
+ vecs = append (vecs , v )
671
+ }
672
+ return vecs
673
+ }
674
+
675
+ func writevRacedetect (iovecs []Iovec , n int ) {
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
+ raceReadRange (unsafe .Pointer (iovecs [i ].Base ), m )
687
+ }
688
+ }
689
+ }
690
+
691
+ func readvRacedetect (iovecs []Iovec , n int , err error ) {
692
+ if ! raceenabled {
693
+ return
694
+ }
695
+ for i := 0 ; n > 0 && i < len (iovecs ); i ++ {
696
+ m := int (iovecs [i ].Len )
697
+ if m > n {
698
+ m = n
699
+ }
700
+ n -= m
701
+ if m > 0 {
702
+ raceWriteRange (unsafe .Pointer (iovecs [i ].Base ), m )
703
+ }
704
+ }
705
+ if err == nil {
706
+ raceAcquire (unsafe .Pointer (& ioSync ))
707
+ }
708
+ }
709
+
710
+ func darwinMajorMinPatch () (maj , min , patch int , err error ) {
711
+ var un Utsname
712
+ err = Uname (& un )
713
+ if err != nil {
714
+ return
715
+ }
716
+
717
+ var mmp [3 ]int
718
+ c := 0
719
+ Loop:
720
+ for _ , b := range un .Release [:] {
721
+ switch {
722
+ case b >= '0' && b <= '9' :
723
+ mmp [c ] = 10 * mmp [c ] + int (b - '0' )
724
+ case b == '.' :
725
+ c ++
726
+ if c > 2 {
727
+ return 0 , 0 , 0 , ENOTSUP
728
+ }
729
+ case b == 0 :
730
+ break Loop
731
+ default :
732
+ return 0 , 0 , 0 , ENOTSUP
733
+ }
734
+ }
735
+ if c != 2 {
736
+ return 0 , 0 , 0 , ENOTSUP
737
+ }
738
+ return mmp [0 ], mmp [1 ], mmp [2 ], nil
739
+ }
740
+
741
+ func darwinKernelVersionMin (maj , min , patch int ) bool {
742
+ actualMaj , actualMin , actualPatch , err := darwinMajorMinPatch ()
743
+ if err != nil {
744
+ return false
745
+ }
746
+ return actualMaj > maj || actualMaj == maj && (actualMin > min || actualMin == min && actualPatch >= patch )
747
+ }
748
+
606
749
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
607
750
608
751
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
@@ -705,3 +848,7 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI
705
848
//sys write(fd int, p []byte) (n int, err error)
706
849
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
707
850
//sys munmap(addr uintptr, length uintptr) (err error)
851
+ //sys readv(fd int, iovecs []Iovec) (n int, err error)
852
+ //sys preadv(fd int, iovecs []Iovec, offset int64) (n int, err error)
853
+ //sys writev(fd int, iovecs []Iovec) (n int, err error)
854
+ //sys pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error)
0 commit comments