@@ -701,3 +701,232 @@ impl<'name, 'bufs, 'control> fmt::Debug for MsgHdrMut<'name, 'bufs, 'control> {
701701 "MsgHdrMut" . fmt ( fmt)
702702 }
703703}
704+
705+ /// Configuration of a `sendmmsg(2)` system call.
706+ ///
707+ /// This wraps `mmsghdr` on Unix. Also see [`MMsgHdrMut`] for the variant used by `recvmmsg(2)`.
708+ /// This API is not available on Windows.
709+ #[ cfg( any(
710+ target_os = "aix" ,
711+ target_os = "android" ,
712+ target_os = "freebsd" ,
713+ target_os = "fuchsia" ,
714+ target_os = "linux" ,
715+ target_os = "netbsd" ,
716+ target_os = "openbsd" ,
717+ ) ) ]
718+ pub struct MMsgHdr < ' addr , ' bufs , ' control > {
719+ inner : sys:: mmsghdr ,
720+ #[ allow( clippy:: type_complexity) ]
721+ _lifetimes : PhantomData < ( & ' addr SockAddr , & ' bufs IoSlice < ' bufs > , & ' control [ u8 ] ) > ,
722+ }
723+
724+ #[ cfg( any(
725+ target_os = "aix" ,
726+ target_os = "android" ,
727+ target_os = "freebsd" ,
728+ target_os = "fuchsia" ,
729+ target_os = "linux" ,
730+ target_os = "netbsd" ,
731+ target_os = "openbsd" ,
732+ ) ) ]
733+ impl < ' addr , ' bufs , ' control > MMsgHdr < ' addr , ' bufs , ' control > {
734+ /// Create a new `MMsgHdr` with all empty/zero fields.
735+ #[ allow( clippy:: new_without_default) ]
736+ pub fn new ( ) -> MMsgHdr < ' addr , ' bufs , ' control > {
737+ // SAFETY: all zero is valid for `mmsghdr`.
738+ MMsgHdr {
739+ inner : unsafe { mem:: zeroed ( ) } ,
740+ _lifetimes : PhantomData ,
741+ }
742+ }
743+
744+ /// Create a new `MMsgHdr` from a `MsgHdr`.
745+ pub fn from_msghdr ( msghdr : MsgHdr < ' addr , ' bufs , ' control > ) -> MMsgHdr < ' addr , ' bufs , ' control > {
746+ MMsgHdr {
747+ inner : sys:: mmsghdr {
748+ msg_hdr : msghdr. inner ,
749+ msg_len : 0 ,
750+ } ,
751+ _lifetimes : PhantomData ,
752+ }
753+ }
754+
755+ /// Set the address (name) of the message.
756+ ///
757+ /// Corresponds to setting `msg_name` and `msg_namelen` on Unix.
758+ pub fn with_addr ( mut self , addr : & ' addr SockAddr ) -> Self {
759+ sys:: set_msghdr_name ( & mut self . inner . msg_hdr , addr) ;
760+ self
761+ }
762+
763+ /// Set the buffer(s) of the message.
764+ ///
765+ /// Corresponds to setting `msg_iov` and `msg_iovlen` on Unix.
766+ pub fn with_buffers ( mut self , bufs : & ' bufs [ IoSlice < ' _ > ] ) -> Self {
767+ let ptr = bufs. as_ptr ( ) as * mut _ ;
768+ sys:: set_msghdr_iov ( & mut self . inner . msg_hdr , ptr, bufs. len ( ) ) ;
769+ self
770+ }
771+
772+ /// Set the control buffer of the message.
773+ ///
774+ /// Corresponds to setting `msg_control` and `msg_controllen` on Unix.
775+ pub fn with_control ( mut self , buf : & ' control [ u8 ] ) -> Self {
776+ let ptr = buf. as_ptr ( ) as * mut _ ;
777+ sys:: set_msghdr_control ( & mut self . inner . msg_hdr , ptr, buf. len ( ) ) ;
778+ self
779+ }
780+
781+ /// Set the flags of the message.
782+ ///
783+ /// Corresponds to setting `msg_flags` on Unix.
784+ pub fn with_flags ( mut self , flags : sys:: c_int ) -> Self {
785+ sys:: set_msghdr_flags ( & mut self . inner . msg_hdr , flags) ;
786+ self
787+ }
788+
789+ /// Gets the number of sent bytes.
790+ ///
791+ /// Corresponds to `msg_len` on Unix.
792+ pub fn data_len ( & self ) -> usize {
793+ self . inner . msg_len as usize
794+ }
795+ }
796+
797+ #[ cfg( any(
798+ target_os = "aix" ,
799+ target_os = "android" ,
800+ target_os = "freebsd" ,
801+ target_os = "fuchsia" ,
802+ target_os = "linux" ,
803+ target_os = "netbsd" ,
804+ target_os = "openbsd" ,
805+ ) ) ]
806+ impl < ' name , ' bufs , ' control > fmt:: Debug for MMsgHdr < ' name , ' bufs , ' control > {
807+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
808+ "MMsgHdr" . fmt ( fmt)
809+ }
810+ }
811+
812+ /// Configuration of a `recvmmsg(2)` system call.
813+ ///
814+ /// This wraps `mmsghdr` on Unix. Also see [`MMsgHdr`] for the variant used by `sendmmsg(2)`.
815+ /// This API is not available on Windows.
816+ #[ cfg( any(
817+ target_os = "aix" ,
818+ target_os = "android" ,
819+ target_os = "freebsd" ,
820+ target_os = "fuchsia" ,
821+ target_os = "linux" ,
822+ target_os = "netbsd" ,
823+ target_os = "openbsd" ,
824+ ) ) ]
825+ pub struct MMsgHdrMut < ' addr , ' bufs , ' control > {
826+ inner : sys:: mmsghdr ,
827+ #[ allow( clippy:: type_complexity) ]
828+ _lifetimes : PhantomData < (
829+ & ' addr mut SockAddr ,
830+ & ' bufs mut MaybeUninitSlice < ' bufs > ,
831+ & ' control mut [ u8 ] ,
832+ ) > ,
833+ }
834+
835+ #[ cfg( any(
836+ target_os = "aix" ,
837+ target_os = "android" ,
838+ target_os = "freebsd" ,
839+ target_os = "fuchsia" ,
840+ target_os = "linux" ,
841+ target_os = "netbsd" ,
842+ target_os = "openbsd" ,
843+ ) ) ]
844+ impl < ' addr , ' bufs , ' control > MMsgHdrMut < ' addr , ' bufs , ' control > {
845+ /// Create a new `MMsgHdrMut` with all empty/zero fields.
846+ #[ allow( clippy:: new_without_default) ]
847+ pub fn new ( ) -> MMsgHdrMut < ' addr , ' bufs , ' control > {
848+ // SAFETY: all zero is valid for `mmsghdr`.
849+ MMsgHdrMut {
850+ inner : unsafe { mem:: zeroed ( ) } ,
851+ _lifetimes : PhantomData ,
852+ }
853+ }
854+
855+ /// Create a new `MMsgHdrMut` from a `MsgHdrMut`.
856+ pub fn from_msghdrmut (
857+ msghdrmut : MsgHdrMut < ' addr , ' bufs , ' control > ,
858+ ) -> MMsgHdrMut < ' addr , ' bufs , ' control > {
859+ MMsgHdrMut {
860+ inner : sys:: mmsghdr {
861+ msg_hdr : msghdrmut. inner ,
862+ msg_len : 0 ,
863+ } ,
864+ _lifetimes : PhantomData ,
865+ }
866+ }
867+
868+ /// Set the mutable address (name) of the message.
869+ ///
870+ /// Corresponds to setting `msg_name` and `msg_namelen` on Unix.
871+ #[ allow( clippy:: needless_pass_by_ref_mut) ]
872+ pub fn with_addr ( mut self , addr : & ' addr mut SockAddr ) -> Self {
873+ sys:: set_msghdr_name ( & mut self . inner . msg_hdr , addr) ;
874+ self
875+ }
876+
877+ /// Set the mutable buffer(s) of the message.
878+ ///
879+ /// Corresponds to setting `msg_iov` and `msg_iovlen` on Unix.
880+ pub fn with_buffers ( mut self , bufs : & ' bufs mut [ MaybeUninitSlice < ' _ > ] ) -> Self {
881+ sys:: set_msghdr_iov (
882+ & mut self . inner . msg_hdr ,
883+ bufs. as_mut_ptr ( ) . cast ( ) ,
884+ bufs. len ( ) ,
885+ ) ;
886+ self
887+ }
888+
889+ /// Set the mutable control buffer of the message.
890+ ///
891+ /// Corresponds to setting `msg_control` and `msg_controllen` on Unix.
892+ pub fn with_control ( mut self , buf : & ' control mut [ MaybeUninit < u8 > ] ) -> Self {
893+ sys:: set_msghdr_control ( & mut self . inner . msg_hdr , buf. as_mut_ptr ( ) . cast ( ) , buf. len ( ) ) ;
894+ self
895+ }
896+
897+ /// Returns the flags of the message.
898+ pub fn flags ( & self ) -> RecvFlags {
899+ sys:: msghdr_flags ( & self . inner . msg_hdr )
900+ }
901+
902+ /// Gets the length of the control buffer.
903+ ///
904+ /// Can be used to determine how much, if any, of the control buffer was filled by `recvmsg`.
905+ ///
906+ /// Corresponds to `msg_controllen` on Unix.
907+ pub fn control_len ( & self ) -> usize {
908+ sys:: msghdr_control_len ( & self . inner . msg_hdr )
909+ }
910+
911+ /// Gets the number of received bytes.
912+ ///
913+ /// Corresponds to `msg_len` on Unix.
914+ pub fn data_len ( & self ) -> usize {
915+ self . inner . msg_len as usize
916+ }
917+ }
918+
919+ #[ cfg( any(
920+ target_os = "aix" ,
921+ target_os = "android" ,
922+ target_os = "freebsd" ,
923+ target_os = "fuchsia" ,
924+ target_os = "linux" ,
925+ target_os = "netbsd" ,
926+ target_os = "openbsd" ,
927+ ) ) ]
928+ impl < ' name , ' bufs , ' control > fmt:: Debug for MMsgHdrMut < ' name , ' bufs , ' control > {
929+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
930+ "MMsgHdrMut" . fmt ( fmt)
931+ }
932+ }
0 commit comments