@@ -39,10 +39,20 @@ pub use self::addr::{SockaddrLike, SockaddrStorage};
39
39
pub use self :: addr:: { AddressFamily , UnixAddr } ;
40
40
#[ cfg( not( solarish) ) ]
41
41
pub use self :: addr:: { AddressFamily , UnixAddr } ;
42
- #[ cfg( not( any( solarish, target_os = "haiku" , target_os = "hurd" , target_os = "redox" ) ) ) ]
42
+ #[ cfg( not( any(
43
+ solarish,
44
+ target_os = "haiku" ,
45
+ target_os = "hurd" ,
46
+ target_os = "redox"
47
+ ) ) ) ]
43
48
#[ cfg( feature = "net" ) ]
44
49
pub use self :: addr:: { LinkAddr , SockaddrIn , SockaddrIn6 } ;
45
- #[ cfg( any( solarish, target_os = "haiku" , target_os = "hurd" , target_os = "redox" ) ) ]
50
+ #[ cfg( any(
51
+ solarish,
52
+ target_os = "haiku" ,
53
+ target_os = "hurd" ,
54
+ target_os = "redox"
55
+ ) ) ]
46
56
#[ cfg( feature = "net" ) ]
47
57
pub use self :: addr:: { SockaddrIn , SockaddrIn6 } ;
48
58
@@ -794,17 +804,17 @@ pub enum ControlMessageOwned {
794
804
#[ cfg_attr( docsrs, doc( cfg( feature = "net" ) ) ) ]
795
805
Ipv6HopLimit ( i32 ) ,
796
806
797
- /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet.
807
+ /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet.
798
808
#[ cfg( any( linux_android, target_os = "freebsd" ) ) ]
799
809
#[ cfg( feature = "net" ) ]
800
810
#[ cfg_attr( docsrs, doc( cfg( feature = "net" ) ) ) ]
801
811
Ipv4Tos ( u8 ) ,
802
812
803
- /// Retrieve the DSCP (Traffic Class) header field of the incoming IPv6 packet.
813
+ /// Retrieve the DSCP (Traffic Class) header field of the incoming IPv6 packet.
804
814
#[ cfg( any( linux_android, target_os = "freebsd" ) ) ]
805
815
#[ cfg( feature = "net" ) ]
806
816
#[ cfg_attr( docsrs, doc( cfg( feature = "net" ) ) ) ]
807
- Ipv6TClass ( i32 ) ,
817
+ Ipv6TClass ( i32 ) ,
808
818
809
819
/// UDP Generic Receive Offload (GRO) allows receiving multiple UDP
810
820
/// packets from a single sender.
@@ -1577,7 +1587,7 @@ impl<'a> ControlMessage<'a> {
1577
1587
/// by ancillary data. Optionally direct the message at the given address,
1578
1588
/// as with sendto.
1579
1589
///
1580
- /// Allocates if cmsgs is nonempty.
1590
+ /// Allocates if cmsgs is nonempty, use [`sendmsg_prealloc()`] if you want to use a pre-allocated buffer .
1581
1591
///
1582
1592
/// # Examples
1583
1593
/// When not directing to any specific address, use `()` for the generic type
@@ -1631,6 +1641,29 @@ pub fn sendmsg<S>(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage],
1631
1641
}
1632
1642
1633
1643
1644
+ /// `sendmsg_prealloc()` is the same as [`sendmsg()`] but it accepts a preallocated
1645
+ /// `cmsg` buffer vector.
1646
+ ///
1647
+ /// Send data in scatter-gather vectors to a socket, possibly accompanied
1648
+ /// by ancillary data. Optionally direct the message at the given address,
1649
+ /// as with sendto.
1650
+ pub fn sendmsg_prealloc<S >( fd: RawFd , iov: & [ IoSlice <' _>] , cmsgs: & [ ControlMessage ] ,
1651
+ flags: MsgFlags , addr: Option <& S >, cmsg_buffer: & mut Vec <u8 >) -> Result <usize >
1652
+ where S : SockaddrLike
1653
+ {
1654
+
1655
+ if cmsg_buffer. len( ) < cmsgs. len( ) {
1656
+ return Err ( Errno :: ENOBUFS ) ;
1657
+ }
1658
+
1659
+ let mhdr = pack_mhdr_to_send( & mut cmsg_buffer[ ..] , iov, cmsgs, addr) ;
1660
+
1661
+ let ret = unsafe { libc:: sendmsg( fd, & mhdr, flags. bits( ) ) } ;
1662
+
1663
+ Errno :: result( ret) . map( |r| r as usize )
1664
+ }
1665
+
1666
+
1634
1667
/// An extension of `sendmsg` that allows the caller to transmit multiple
1635
1668
/// messages on a socket using a single system call. This has performance
1636
1669
/// benefits for some applications.
@@ -2456,4 +2489,3 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
2456
2489
Errno :: result ( shutdown ( df, how) ) . map ( drop)
2457
2490
}
2458
2491
}
2459
-
0 commit comments