diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 99b47a5905..35cb4100ab 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -39,10 +39,20 @@ pub use self::addr::{SockaddrLike, SockaddrStorage}; pub use self::addr::{AddressFamily, UnixAddr}; #[cfg(not(solarish))] pub use self::addr::{AddressFamily, UnixAddr}; -#[cfg(not(any(solarish, target_os = "haiku", target_os = "hurd", target_os = "redox")))] +#[cfg(not(any( + solarish, + target_os = "haiku", + target_os = "hurd", + target_os = "redox" +)))] #[cfg(feature = "net")] pub use self::addr::{LinkAddr, SockaddrIn, SockaddrIn6}; -#[cfg(any(solarish, target_os = "haiku", target_os = "hurd", target_os = "redox"))] +#[cfg(any( + solarish, + target_os = "haiku", + target_os = "hurd", + target_os = "redox" +))] #[cfg(feature = "net")] pub use self::addr::{SockaddrIn, SockaddrIn6}; @@ -794,17 +804,17 @@ pub enum ControlMessageOwned { #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6HopLimit(i32), - /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. + /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4Tos(u8), - /// Retrieve the DSCP (Traffic Class) header field of the incoming IPv6 packet. + /// Retrieve the DSCP (Traffic Class) header field of the incoming IPv6 packet. #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - Ipv6TClass(i32), + Ipv6TClass(i32), /// UDP Generic Receive Offload (GRO) allows receiving multiple UDP /// packets from a single sender. @@ -1577,7 +1587,7 @@ impl<'a> ControlMessage<'a> { /// by ancillary data. Optionally direct the message at the given address, /// as with sendto. /// -/// Allocates if cmsgs is nonempty. +/// Allocates if cmsgs is nonempty, use [`sendmsg_pre_alloc()`] if you want to use a pre-allocated buffer. /// /// # Examples /// When not directing to any specific address, use `()` for the generic type @@ -1631,6 +1641,24 @@ pub fn sendmsg(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage], } +/// `sendmsg_pre_alloc()` is the same as [`sendmsg()`] but it accepts a preallocated +/// `cmsg` buffer vector. +/// +/// Send data in scatter-gather vectors to a socket, possibly accompanied +/// by ancillary data. Optionally direct the message at the given address, +/// as with sendto. +pub fn sendmsg_pre_alloc(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage], + flags: MsgFlags, addr: Option<&S>, cmsg_buffer: &mut Vec) -> Result + where S: SockaddrLike +{ + let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], iov, cmsgs, addr); + + let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) }; + + Errno::result(ret).map(|r| r as usize) +} + + /// An extension of `sendmsg` that allows the caller to transmit multiple /// messages on a socket using a single system call. This has performance /// benefits for some applications. @@ -2456,4 +2484,3 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> { Errno::result(shutdown(df, how)).map(drop) } } -