Skip to main content

dope_sys/io/socket/msg/
mod.rs

1use std::ptr;
2
3use crate::io::socket::addr;
4
5pub mod source;
6
7/// Exact message flags one receive reported for its payload.
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9#[repr(transparent)]
10pub struct Flags(u32);
11
12impl Flags {
13    pub const NONE: Self = Self(0);
14
15    pub const fn new(bits: u32) -> Self {
16        Self(bits)
17    }
18
19    /// Whether the kernel truncated the received payload.
20    pub const fn is_truncated(self) -> bool {
21        self.0 & libc::MSG_TRUNC as u32 != 0
22    }
23
24    /// Raw reported bits, for exact diagnostics.
25    pub const fn raw(self) -> u32 {
26        self.0
27    }
28}
29
30/// One native scatter/gather extent.
31///
32/// Values carry no borrow by themselves; installing them in a [`Header`] and
33/// freezing that header retains the bytes they point at.
34#[derive(Clone, Copy)]
35#[repr(transparent)]
36pub struct Iovec(pub(super) libc::iovec);
37
38impl Iovec {
39    #[must_use]
40    pub const fn empty() -> Self {
41        Self(libc::iovec {
42            iov_base: ptr::null_mut(),
43            iov_len: 0,
44        })
45    }
46
47    #[must_use]
48    pub fn from_slice(bytes: &[u8]) -> Self {
49        Self(libc::iovec {
50            iov_base: bytes.as_ptr().cast_mut().cast(),
51            iov_len: bytes.len(),
52        })
53    }
54
55    /// Exact byte extent this entry covers.
56    #[must_use]
57    pub const fn len(self) -> usize {
58        self.0.iov_len
59    }
60
61    pub const fn is_empty(self) -> bool {
62        self.len() == 0
63    }
64}
65
66/// One native message header over caller-owned extents.
67///
68/// The value is deliberately not `Copy`: a configured header is the root of a
69/// raw pointer graph and is frozen through the caller's message type.
70#[repr(transparent)]
71pub struct Header(libc::msghdr);
72
73impl Header {
74    #[must_use]
75    pub const fn new() -> Self {
76        Self(libc::msghdr {
77            msg_name: ptr::null_mut(),
78            msg_namelen: 0,
79            msg_iov: ptr::null_mut(),
80            msg_iovlen: 0,
81            msg_control: ptr::null_mut(),
82            msg_controllen: 0,
83            msg_flags: 0,
84        })
85    }
86
87    /// Installs one exact address view as this header's destination.
88    pub fn name(&mut self, addr: addr::Addr<'_>) {
89        let (addr, len) = addr.parts();
90        self.0.msg_name = addr.cast_mut().cast();
91        self.0.msg_namelen = len.raw();
92    }
93
94    /// Installs ancillary bytes whose borrow the caller retains.
95    pub fn control(&mut self, control: &[u8]) {
96        self.0.msg_control = control.as_ptr().cast_mut().cast();
97        self.0.msg_controllen = control.len() as _;
98    }
99
100    /// Installs the exact extent list as this header's scatter/gather vector.
101    pub fn bind(&mut self, iovecs: &[Iovec]) {
102        self.0.msg_iov = if iovecs.is_empty() {
103            ptr::null_mut()
104        } else {
105            iovecs.as_ptr().cast_mut().cast()
106        };
107        self.0.msg_iovlen = iovecs.len() as _;
108    }
109
110    pub(crate) const fn as_raw(&self) -> &libc::msghdr {
111        &self.0
112    }
113}
114
115impl Default for Header {
116    fn default() -> Self {
117        Self::new()
118    }
119}