@@ -701,3 +701,230 @@ 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 ( msghdrmut : MsgHdrMut < ' addr , ' bufs , ' control > ) -> MMsgHdrMut < ' addr , ' bufs , ' control > {
857+ MMsgHdrMut {
858+ inner : sys:: mmsghdr {
859+ msg_hdr : msghdrmut. inner ,
860+ msg_len : 0 ,
861+ } ,
862+ _lifetimes : PhantomData ,
863+ }
864+ }
865+
866+ /// Set the mutable address (name) of the message.
867+ ///
868+ /// Corresponds to setting `msg_name` and `msg_namelen` on Unix.
869+ #[ allow( clippy:: needless_pass_by_ref_mut) ]
870+ pub fn with_addr ( mut self , addr : & ' addr mut SockAddr ) -> Self {
871+ sys:: set_msghdr_name ( & mut self . inner . msg_hdr , addr) ;
872+ self
873+ }
874+
875+ /// Set the mutable buffer(s) of the message.
876+ ///
877+ /// Corresponds to setting `msg_iov` and `msg_iovlen` on Unix.
878+ pub fn with_buffers ( mut self , bufs : & ' bufs mut [ MaybeUninitSlice < ' _ > ] ) -> Self {
879+ sys:: set_msghdr_iov (
880+ & mut self . inner . msg_hdr ,
881+ bufs. as_mut_ptr ( ) . cast ( ) ,
882+ bufs. len ( ) ,
883+ ) ;
884+ self
885+ }
886+
887+ /// Set the mutable control buffer of the message.
888+ ///
889+ /// Corresponds to setting `msg_control` and `msg_controllen` on Unix.
890+ pub fn with_control ( mut self , buf : & ' control mut [ MaybeUninit < u8 > ] ) -> Self {
891+ sys:: set_msghdr_control ( & mut self . inner . msg_hdr , buf. as_mut_ptr ( ) . cast ( ) , buf. len ( ) ) ;
892+ self
893+ }
894+
895+ /// Returns the flags of the message.
896+ pub fn flags ( & self ) -> RecvFlags {
897+ sys:: msghdr_flags ( & self . inner . msg_hdr )
898+ }
899+
900+ /// Gets the length of the control buffer.
901+ ///
902+ /// Can be used to determine how much, if any, of the control buffer was filled by `recvmsg`.
903+ ///
904+ /// Corresponds to `msg_controllen` on Unix.
905+ pub fn control_len ( & self ) -> usize {
906+ sys:: msghdr_control_len ( & self . inner . msg_hdr )
907+ }
908+
909+ /// Gets the number of received bytes.
910+ ///
911+ /// Corresponds to `msg_len` on Unix.
912+ pub fn data_len ( & self ) -> usize {
913+ self . inner . msg_len as usize
914+ }
915+ }
916+
917+ #[ cfg( any(
918+ target_os = "aix" ,
919+ target_os = "android" ,
920+ target_os = "freebsd" ,
921+ target_os = "fuchsia" ,
922+ target_os = "linux" ,
923+ target_os = "netbsd" ,
924+ target_os = "openbsd" ,
925+ ) ) ]
926+ impl < ' name , ' bufs , ' control > fmt:: Debug for MMsgHdrMut < ' name , ' bufs , ' control > {
927+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
928+ "MMsgHdrMut" . fmt ( fmt)
929+ }
930+ }
0 commit comments