usecrate::sys::HANDLE_QUEUE_LIMIT; use bytes::{BufMut, BytesMut}; use libc::cmsghdr; use std::convert::TryInto; use std::os::unix::io::RawFd; use std::{mem, slice};
trait AsBytes { fn as_bytes(&self) -> &[u8];
}
impl<'a, T: Sized> AsBytes for &'a [T] { fn as_bytes(&self) -> &[u8] { // TODO: This should account for the alignment of T let byte_count = std::mem::size_of_val(*self); unsafe { slice::from_raw_parts(self.as_ptr() as *const _, byte_count) }
}
}
// Encode `handles` into a cmsghdr in `buf`. pubfn encode_handles(cmsg: &mut BytesMut, handles: &[RawFd]) {
assert!(handles.len() <= HANDLE_QUEUE_LIMIT); let msg = handles.as_bytes();
let cmsg_space = space(msg.len());
assert!(cmsg.remaining_mut() >= cmsg_space);
// Some definitions of cmsghdr contain padding. Rather // than try to keep an up-to-date #cfg list to handle // that, just use a pre-zeroed struct to fill out any // fields we don't care about. let zeroed = unsafe { mem::zeroed() }; #[allow(clippy::needless_update)] // `cmsg_len` is `usize` on some platforms, `u32` on others. #[allow(clippy::useless_conversion)] let cmsghdr = cmsghdr {
cmsg_len: len(msg.len()).try_into().unwrap(),
cmsg_level: libc::SOL_SOCKET,
cmsg_type: libc::SCM_RIGHTS,
..zeroed
};
unsafe { let cmsghdr_ptr = cmsg.chunk_mut().as_mut_ptr();
std::ptr::copy_nonoverlapping(
&cmsghdr as *const _ as *const _,
cmsghdr_ptr,
mem::size_of::<cmsghdr>(),
); let cmsg_data_ptr = libc::CMSG_DATA(cmsghdr_ptr as _);
std::ptr::copy_nonoverlapping(msg.as_ptr(), cmsg_data_ptr, msg.len());
cmsg.advance_mut(cmsg_space);
}
}
// Decode `buf` containing a cmsghdr with one or more handle(s). pubfn decode_handles(buf: &mut BytesMut) -> arrayvec::ArrayVec<RawFd, HANDLE_QUEUE_LIMIT> { letmut fds = arrayvec::ArrayVec::<RawFd, HANDLE_QUEUE_LIMIT>::new();
let cmsghdr_len = len(0);
if buf.len() < cmsghdr_len { // No more entries---not enough data in `buf` for a // complete message. return fds;
}
let cmsg: &cmsghdr = unsafe { &*(buf.as_ptr() as *const _) }; #[allow(clippy::unnecessary_cast)] // `cmsg_len` type is platform-dependent. let cmsg_len = cmsg.cmsg_len as usize;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.