Skip to content

Commit 7aee29b

Browse files
committed
Add preallocated buffer version of sendmsg
1 parent e5ac667 commit 7aee29b

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

src/sys/socket/mod.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,20 @@ pub use self::addr::{SockaddrLike, SockaddrStorage};
3939
pub use self::addr::{AddressFamily, UnixAddr};
4040
#[cfg(not(solarish))]
4141
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+
)))]
4348
#[cfg(feature = "net")]
4449
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+
))]
4656
#[cfg(feature = "net")]
4757
pub use self::addr::{SockaddrIn, SockaddrIn6};
4858

@@ -794,17 +804,17 @@ pub enum ControlMessageOwned {
794804
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
795805
Ipv6HopLimit(i32),
796806

797-
/// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet.
807+
/// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet.
798808
#[cfg(any(linux_android, target_os = "freebsd"))]
799809
#[cfg(feature = "net")]
800810
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
801811
Ipv4Tos(u8),
802812

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.
804814
#[cfg(any(linux_android, target_os = "freebsd"))]
805815
#[cfg(feature = "net")]
806816
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
807-
Ipv6TClass(i32),
817+
Ipv6TClass(i32),
808818

809819
/// UDP Generic Receive Offload (GRO) allows receiving multiple UDP
810820
/// packets from a single sender.
@@ -1577,7 +1587,7 @@ impl<'a> ControlMessage<'a> {
15771587
/// by ancillary data. Optionally direct the message at the given address,
15781588
/// as with sendto.
15791589
///
1580-
/// Allocates if cmsgs is nonempty.
1590+
/// Allocates if cmsgs is nonempty, use [`sendmsg_pre_alloc()`] if you want to use a pre-allocated buffer.
15811591
///
15821592
/// # Examples
15831593
/// When not directing to any specific address, use `()` for the generic type
@@ -1631,6 +1641,24 @@ pub fn sendmsg<S>(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage],
16311641
}
16321642

16331643

1644+
/// `sendmsg_pre_alloc()` 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_pre_alloc<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+
let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], iov, cmsgs, addr);
1655+
1656+
let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) };
1657+
1658+
Errno::result(ret).map(|r| r as usize)
1659+
}
1660+
1661+
16341662
/// An extension of `sendmsg` that allows the caller to transmit multiple
16351663
/// messages on a socket using a single system call. This has performance
16361664
/// benefits for some applications.
@@ -2456,4 +2484,3 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
24562484
Errno::result(shutdown(df, how)).map(drop)
24572485
}
24582486
}
2459-

0 commit comments

Comments
 (0)