Skip to content

Commit 0e2f962

Browse files
committed
Add MsgHdrMut type
To be used in recvmsg(2) calls.
1 parent 49b844f commit 0e2f962

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

src/lib.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,70 @@ impl<'name, 'bufs, 'control> fmt::Debug for MsgHdr<'name, 'bufs, 'control> {
636636
"MsgHdr".fmt(fmt)
637637
}
638638
}
639+
640+
/// Configuration of a `recvmsg(2)` system call.
641+
///
642+
/// This wraps `msghdr` on Unix and `WSAMSG` on Windows. Also see [`MsgHdr`] for
643+
/// the variant used by `sendmsg(2)`.
644+
#[cfg(not(target_os = "redox"))]
645+
pub struct MsgHdrMut<'addr, 'bufs, 'control> {
646+
inner: sys::msghdr,
647+
#[allow(clippy::type_complexity)]
648+
_lifetimes: PhantomData<(
649+
&'addr mut SockAddr,
650+
&'bufs mut MaybeUninitSlice<'bufs>,
651+
&'control mut [u8],
652+
)>,
653+
}
654+
655+
#[cfg(not(target_os = "redox"))]
656+
impl<'addr, 'bufs, 'control> MsgHdrMut<'addr, 'bufs, 'control> {
657+
/// Create a new `MsgHdrMut` with all empty/zero fields.
658+
#[allow(clippy::new_without_default)]
659+
pub fn new() -> MsgHdrMut<'addr, 'bufs, 'control> {
660+
// SAFETY: all zero is valid for `msghdr` and `WSAMSG`.
661+
MsgHdrMut {
662+
inner: unsafe { mem::zeroed() },
663+
_lifetimes: PhantomData,
664+
}
665+
}
666+
667+
/// Set the mutable address (name) of the message.
668+
///
669+
/// Corresponds to setting `msg_name` and `msg_namelen` on Unix and `name`
670+
/// and `namelen` on Windows.
671+
pub fn with_addr(mut self, addr: &'addr mut SockAddr) -> Self {
672+
sys::set_msghdr_name(&mut self.inner, addr);
673+
self
674+
}
675+
676+
/// Set the mutable buffer(s) of the message.
677+
///
678+
/// Corresponds to setting `msg_iov` and `msg_iovlen` on Unix and `lpBuffers`
679+
/// and `dwBufferCount` on Windows.
680+
pub fn with_buffers(mut self, bufs: &'bufs mut [MaybeUninitSlice<'bufs>]) -> Self {
681+
sys::set_msghdr_iov(&mut self.inner, bufs.as_mut_ptr().cast(), bufs.len());
682+
self
683+
}
684+
685+
/// Set the mutable control buffer of the message.
686+
///
687+
/// Corresponds to setting `msg_control` and `msg_controllen` on Unix and
688+
/// `Control` on Windows.
689+
pub fn with_control(mut self, buf: &'control mut [MaybeUninit<u8>]) -> Self {
690+
sys::set_msghdr_control(&mut self.inner, buf.as_mut_ptr().cast(), buf.len());
691+
self
692+
}
693+
694+
/// Returns the flags of the message.
695+
pub fn flags(&self) -> RecvFlags {
696+
sys::msghdr_flags(&self.inner)
697+
}
698+
}
699+
700+
#[cfg(not(target_os = "redox"))]
701+
impl<'name, 'bufs, 'control> fmt::Debug for MsgHdrMut<'name, 'bufs, 'control> {
702+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
703+
"MsgHdrMut".fmt(fmt)
704+
}
705+
}

src/sys/unix.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,11 @@ pub(crate) fn set_msghdr_flags(msg: &mut msghdr, flags: libc::c_int) {
669669
msg.msg_flags = flags;
670670
}
671671

672+
#[cfg(not(target_os = "redox"))]
673+
pub(crate) fn msghdr_flags(msg: &msghdr) -> RecvFlags {
674+
RecvFlags(msg.msg_flags)
675+
}
676+
672677
/// Unix only API.
673678
impl SockAddr {
674679
/// Constructs a `SockAddr` with the family `AF_VSOCK` and the provided CID/port.

src/sys/windows.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use windows_sys::Win32::Networking::WinSock::{
2828
};
2929
use windows_sys::Win32::System::Threading::INFINITE;
3030

31-
use crate::{MsgHdr, RecvFlags, SockAddr, TcpKeepalive, Type};
31+
use crate::{MsgHdr, MsgHdrMut, RecvFlags, SockAddr, TcpKeepalive, Type};
3232

3333
#[allow(non_camel_case_types)]
3434
pub(crate) type c_int = std::os::raw::c_int;
@@ -209,6 +209,10 @@ pub(crate) fn set_msghdr_flags(msg: &mut msghdr, flags: c_int) {
209209
msg.dwFlags = flags as u32;
210210
}
211211

212+
pub(crate) fn msghdr_flags(msg: &msghdr) -> RecvFlags {
213+
RecvFlags(msg.dwFlags as c_int)
214+
}
215+
212216
fn init() {
213217
static INIT: Once = Once::new();
214218

0 commit comments

Comments
 (0)