use std::io;
use std::mem;
use std::os::unix::io::{AsRawFd, BorrowedFd};
use crate::platform;
pub(crate) struct RecvMsgResult {
pub bytes_read: usize,
pub ancillary_len: usize,
pub truncated: bool,
}
pub(crate) fn sendmsg_vectored(
fd: BorrowedFd<'_>,
iov: &[io::IoSlice<'_>],
ancillary_buf: &[u8],
ancillary_len: usize,
) -> io::Result<usize> {
let mut msg: libc::msghdr = unsafe { mem::zeroed() };
msg.msg_iov = iov.as_ptr() as *mut libc::iovec;
msg.msg_iovlen = iov.len() as _;
if ancillary_len > 0 {
msg.msg_control = ancillary_buf.as_ptr() as *mut libc::c_void;
msg.msg_controllen = ancillary_len as _;
}
let ret = unsafe { libc::sendmsg(fd.as_raw_fd(), &msg, 0) };
if ret < 0 {
Err(io::Error::last_os_error())
} else {
Ok(ret as usize)
}
}
pub(crate) fn recvmsg_vectored(
fd: BorrowedFd<'_>,
iov: &mut [io::IoSliceMut<'_>],
ancillary_buf: &mut [u8],
) -> io::Result<RecvMsgResult> {
let mut msg: libc::msghdr = unsafe { mem::zeroed() };
msg.msg_iov = iov.as_mut_ptr() as *mut libc::iovec;
msg.msg_iovlen = iov.len() as _;
msg.msg_control = ancillary_buf.as_mut_ptr() as *mut libc::c_void;
msg.msg_controllen = ancillary_buf.len() as _;
let ret = unsafe { libc::recvmsg(fd.as_raw_fd(), &mut msg, platform::RECV_FLAGS) };
if ret < 0 {
return Err(io::Error::last_os_error());
}
#[allow(clippy::unnecessary_cast)]
let ancillary_len = msg.msg_controllen as usize;
let truncated = (msg.msg_flags & libc::MSG_CTRUNC) != 0;
platform::cloexec_received(&ancillary_buf[..ancillary_len])?;
Ok(RecvMsgResult {
bytes_read: ret as usize,
ancillary_len,
truncated,
})
}