Skip to main content

dope_sys/io/socket/
raw.rs

1use std::{
2    os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd},
3    slice,
4};
5
6use libc::socklen_t;
7use o3::{base::num::bounded, buffer};
8
9use crate::{
10    Errno,
11    io::{
12        fd,
13        socket::{Create, Domain, Kind, Setup, accept, msg},
14    },
15    kernel::{self, errno},
16    memory,
17};
18
19/// Receives streams or datagrams into caller-owned native storage.
20pub trait Receive {
21    fn recv(&self, output: buffer::raw::Output<'_>) -> Result<Option<()>, Errno>;
22
23    /// # Safety
24    /// Output belongs to a datagram pool with at least sixteen metadata bytes
25    /// followed by sockaddr_storage and the admitted payload capacity.
26    unsafe fn receive(&self, output: buffer::raw::Output<'_>) -> Result<(), Errno>;
27}
28
29pub trait Open: AsFd + Sized {
30    fn open(domain: Domain, kind: Kind) -> Result<Self, Create>;
31
32    fn adopt(file: OwnedFd) -> Result<Self, Setup>;
33
34    /// # Safety
35    /// Both pointers are null, or name writable full address storage and its returned length.
36    /// The caller retains that storage through the returned completion.
37    unsafe fn accept(
38        &self,
39        addr: *mut libc::sockaddr_storage,
40        len: *mut socklen_t,
41    ) -> Result<Self, accept::Error>;
42}
43
44/// Native access to operations retaining caller-owned socket storage.
45pub trait Source: errno::Source {
46    /// # Safety
47    /// Both pointers are null, or name writable sockaddr storage and its capacity
48    /// for this call. The caller retains that storage through the returned completion.
49    unsafe fn accept<E: From<Errno>>(
50        file: BorrowedFd<'_>,
51        addr: *mut libc::sockaddr,
52        len: *mut socklen_t,
53    ) -> Result<OwnedFd, E> {
54        let raw = unsafe { libc::accept(file.as_raw_fd(), addr, len) };
55        unsafe { <OwnedFd as fd::raw::Adopt>::try_adopt::<Self, E>(raw) }
56    }
57
58    /// # Safety
59    /// The pointer retains a readable input prefix of exactly `len` bytes for this
60    /// call. Its original extent preserves the ABI bound and owns the input graph.
61    unsafe fn send<X: memory::raw::Extent, E: From<Errno>>(
62        file: BorrowedFd<'_>,
63        ptr: *const u8,
64        len: X::Length,
65    ) -> Result<X::Length, E> {
66        let len: bounded::U32<0, { i32::MAX as u32 }> = len.into();
67        let capacity = len.get() as usize;
68        let raw = unsafe { libc::send(file.as_raw_fd(), ptr.cast(), capacity, libc::MSG_NOSIGNAL) };
69        // SAFETY: send completes at most the admitted c_int-bounded input extent.
70        Ok(
71            unsafe { kernel::raw::Status::from_count(raw).try_count::<Self, E>() }?
72                .bounded()
73                .into(),
74        )
75    }
76
77    /// # Safety
78    /// Header is the frozen root of a live input graph, with a total byte count
79    /// bounded by `i32::MAX`; its pointees outlive this call.
80    unsafe fn sendmsg<E: From<Errno>>(
81        file: BorrowedFd<'_>,
82        header: &msg::Header,
83        flags: libc::c_int,
84    ) -> Result<bounded::U32<0, { i32::MAX as u32 }>, E> {
85        let raw = unsafe { libc::sendmsg(file.as_raw_fd(), header.as_raw(), flags) };
86        // SAFETY: the retained header has a total extent bounded by c_int.
87        Ok(unsafe { kernel::raw::Status::from_count(raw).try_count::<Self, E>() }?.bounded())
88    }
89}
90
91impl<T: errno::Source> Source for T {}
92
93/// Projection of a native iovec whose retained input graph proves its lifetime.
94pub trait Iovec {
95    /// # Safety
96    /// The descriptor must point to initialized bytes retained for the returned lifetime.
97    unsafe fn as_slice<'a>(&self) -> &'a [u8];
98}
99
100impl Iovec for msg::Iovec {
101    unsafe fn as_slice<'a>(&self) -> &'a [u8] {
102        if self.is_empty() {
103            return &[];
104        }
105        // SAFETY: the caller retains this nonempty descriptor's complete input bytes.
106        unsafe { slice::from_raw_parts(self.0.iov_base.cast(), self.0.iov_len) }
107    }
108}