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