@@ -602,7 +602,150 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI
602602 return
603603}
604604
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+
606749//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
607750
608751//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
705848//sys write(fd int, p []byte) (n int, err error)
706849//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
707850//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