66// option. This file may not be copied, modified, or distributed
77// except according to those terms.
88
9+ #[ cfg( not( target_os = "redox" ) ) ]
10+ use std:: io:: { IoSlice , IoSliceMut } ;
911use std:: io:: { Read , Write } ;
1012use std:: net:: Shutdown ;
1113use std:: net:: { self , Ipv4Addr , Ipv6Addr } ;
@@ -79,6 +81,20 @@ macro_rules! syscall {
7981 } } ;
8082}
8183
84+ #[ cfg( any( target_os = "android" , all( target_os = "linux" , target_env = "gnu" ) ) ) ]
85+ type IovLen = usize ;
86+
87+ #[ cfg( any(
88+ target_os = "dragonfly" ,
89+ target_os = "freebsd" ,
90+ target_os = "ios" ,
91+ all( target_os = "linux" , target_env = "musl" , ) ,
92+ target_os = "macos" ,
93+ target_os = "netbsd" ,
94+ target_os = "openbsd" ,
95+ ) ) ]
96+ type IovLen = c_int ;
97+
8298/// Unix only API.
8399impl Domain {
84100 /// Domain for Unix socket communication, corresponding to `AF_UNIX`.
@@ -488,6 +504,51 @@ impl Socket {
488504 Ok ( ( n as usize , addr) )
489505 }
490506
507+ #[ cfg( not( target_os = "redox" ) ) ]
508+ pub fn recv_vectored (
509+ & self ,
510+ bufs : & mut [ IoSliceMut < ' _ > ] ,
511+ flags : c_int ,
512+ ) -> io:: Result < ( usize , bool ) > {
513+ let mut msg = libc:: msghdr {
514+ msg_name : std:: ptr:: null_mut ( ) ,
515+ msg_namelen : 0 ,
516+ msg_iov : bufs. as_mut_ptr ( ) . cast ( ) ,
517+ msg_iovlen : bufs. len ( ) . min ( IovLen :: MAX as usize ) as IovLen ,
518+ msg_control : std:: ptr:: null_mut ( ) ,
519+ msg_controllen : 0 ,
520+ msg_flags : 0 ,
521+ } ;
522+
523+ let n = syscall ! ( recvmsg( self . fd, & mut msg as * mut _, flags) ) ?;
524+ let truncated = msg. msg_flags & libc:: MSG_TRUNC != 0 ;
525+ Ok ( ( n as usize , truncated) )
526+ }
527+
528+ #[ cfg( not( target_os = "redox" ) ) ]
529+ pub fn recv_from_vectored (
530+ & self ,
531+ bufs : & mut [ IoSliceMut < ' _ > ] ,
532+ flags : c_int ,
533+ ) -> io:: Result < ( usize , bool , SockAddr ) > {
534+ let mut storage: libc:: sockaddr_storage = unsafe { mem:: zeroed ( ) } ;
535+ let mut msg = libc:: msghdr {
536+ msg_name : & mut storage as * mut libc:: sockaddr_storage as * mut c_void ,
537+ msg_namelen : mem:: size_of_val ( & storage) as socklen_t ,
538+ msg_iov : bufs. as_mut_ptr ( ) . cast ( ) ,
539+ msg_iovlen : bufs. len ( ) . min ( IovLen :: MAX as usize ) as IovLen ,
540+ msg_control : std:: ptr:: null_mut ( ) ,
541+ msg_controllen : 0 ,
542+ msg_flags : 0 ,
543+ } ;
544+
545+ let n = syscall ! ( recvmsg( self . fd, & mut msg as * mut _, flags) ) ?;
546+ let truncated = msg. msg_flags & libc:: MSG_TRUNC != 0 ;
547+ let addr =
548+ unsafe { SockAddr :: from_raw_parts ( & storage as * const _ as * const _ , msg. msg_namelen ) } ;
549+ Ok ( ( n as usize , truncated, addr) )
550+ }
551+
491552 pub fn send ( & self , buf : & [ u8 ] , flags : c_int ) -> io:: Result < usize > {
492553 let n = syscall ! ( send(
493554 self . fd,
@@ -510,6 +571,43 @@ impl Socket {
510571 Ok ( n as usize )
511572 }
512573
574+ #[ cfg( not( target_os = "redox" ) ) ]
575+ pub fn send_vectored ( & self , bufs : & [ IoSlice < ' _ > ] , flags : c_int ) -> io:: Result < usize > {
576+ let mut msg = libc:: msghdr {
577+ msg_name : std:: ptr:: null_mut ( ) ,
578+ msg_namelen : 0 ,
579+ msg_iov : bufs. as_ptr ( ) as * mut libc:: iovec ,
580+ msg_iovlen : bufs. len ( ) . min ( IovLen :: MAX as usize ) as IovLen ,
581+ msg_control : std:: ptr:: null_mut ( ) ,
582+ msg_controllen : 0 ,
583+ msg_flags : 0 ,
584+ } ;
585+
586+ let n = syscall ! ( sendmsg( self . fd, & mut msg as * mut libc:: msghdr, flags) ) ?;
587+ Ok ( n as usize )
588+ }
589+
590+ #[ cfg( not( target_os = "redox" ) ) ]
591+ pub fn send_to_vectored (
592+ & self ,
593+ bufs : & [ IoSlice < ' _ > ] ,
594+ flags : c_int ,
595+ addr : & SockAddr ,
596+ ) -> io:: Result < usize > {
597+ let mut msg = libc:: msghdr {
598+ msg_name : addr. as_ptr ( ) as * mut c_void ,
599+ msg_namelen : addr. len ( ) ,
600+ msg_iov : bufs. as_ptr ( ) as * mut libc:: iovec ,
601+ msg_iovlen : bufs. len ( ) . min ( IovLen :: MAX as usize ) as IovLen ,
602+ msg_control : std:: ptr:: null_mut ( ) ,
603+ msg_controllen : 0 ,
604+ msg_flags : 0 ,
605+ } ;
606+
607+ let n = syscall ! ( sendmsg( self . fd, & mut msg as * mut libc:: msghdr, flags) ) ?;
608+ Ok ( n as usize )
609+ }
610+
513611 pub fn ttl ( & self ) -> io:: Result < u32 > {
514612 unsafe {
515613 let raw: c_int = self . getsockopt ( libc:: IPPROTO_IP , libc:: IP_TTL ) ?;
0 commit comments