#![allow(unsafe_code)]
use crate::backend::c;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::addr::SocketAddrArg;
use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrBuf};
use core::ptr::null_mut;
fn msg_iov_len(len: usize) -> c::size_t {
len as c::size_t
}
fn msg_control_len(len: usize) -> c::size_t {
len as c::size_t
}
pub(crate) unsafe fn with_recv_msghdr<R>(
name: &mut SocketAddrBuf,
iov: &mut [IoSliceMut<'_>],
control: &mut RecvAncillaryBuffer<'_>,
f: impl FnOnce(&mut c::msghdr) -> io::Result<R>,
) -> io::Result<R> {
control.clear();
let mut msghdr = c::msghdr {
msg_name: name.storage.as_mut_ptr().cast(),
msg_namelen: bitcast!(name.len),
msg_iov: iov.as_mut_ptr().cast(),
msg_iovlen: msg_iov_len(iov.len()),
msg_control: control.as_control_ptr().cast(),
msg_controllen: msg_control_len(control.control_len()),
msg_flags: 0,
};
let res = f(&mut msghdr);
if res.is_ok() {
control.set_control_len(msghdr.msg_controllen as usize);
}
name.len = bitcast!(msghdr.msg_namelen);
res
}
pub(crate) fn noaddr_msghdr(
iov: &[IoSlice<'_>],
control: &mut SendAncillaryBuffer<'_, '_, '_>,
) -> c::msghdr {
c::msghdr {
msg_name: null_mut(),
msg_namelen: 0,
msg_iov: iov.as_ptr() as _,
msg_iovlen: msg_iov_len(iov.len()),
msg_control: control.as_control_ptr().cast(),
msg_controllen: msg_control_len(control.control_len()),
msg_flags: 0,
}
}
pub(crate) unsafe fn with_msghdr<R>(
addr: &impl SocketAddrArg,
iov: &[IoSlice<'_>],
control: &mut SendAncillaryBuffer<'_, '_, '_>,
f: impl FnOnce(&c::msghdr) -> R,
) -> R {
addr.with_sockaddr(|addr_ptr, addr_len| {
let mut msghdr = noaddr_msghdr(iov, control);
msghdr.msg_name = addr_ptr as _;
msghdr.msg_namelen = bitcast!(addr_len);
f(&msghdr)
})
}
pub(crate) fn zero_msghdr() -> c::msghdr {
c::msghdr {
msg_name: null_mut(),
msg_namelen: 0,
msg_iov: null_mut(),
msg_iovlen: 0,
msg_control: null_mut(),
msg_controllen: 0,
msg_flags: 0,
}
}