dope_sys/io/socket/
raw.rs1use std::{
2 os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd},
3 slice,
4};
5
6use libc::socklen_t;
7use o3::{base::num::bounded, buffer, buffer::pool};
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
19pub trait Receive {
21 fn recv<'a>(
22 &self,
23 output: buffer::raw::Output<'a>,
24 ) -> Result<Option<pool::Complete<'a>>, Errno>;
25
26 unsafe fn receive<'a>(
30 &self,
31 output: buffer::raw::Output<'a>,
32 ) -> Result<pool::Complete<'a>, Errno>;
33}
34
35pub trait Open: AsFd + Sized {
36 fn open(domain: Domain, kind: Kind) -> Result<Self, Create>;
37
38 fn adopt(file: OwnedFd) -> Result<Self, Setup>;
39
40 unsafe fn accept(
44 &self,
45 addr: *mut libc::sockaddr_storage,
46 len: *mut socklen_t,
47 ) -> Result<Self, accept::Error>;
48}
49
50pub trait Source: errno::Source {
52 unsafe fn accept<E: From<Errno>>(
56 file: BorrowedFd<'_>,
57 addr: *mut libc::sockaddr,
58 len: *mut socklen_t,
59 ) -> Result<OwnedFd, E> {
60 let raw = unsafe { libc::accept(file.as_raw_fd(), addr, len) };
61 unsafe {
62 <OwnedFd as fd::raw::Adopt>::try_adopt(raw, || kernel::raw::Code::last::<Self>().into())
63 }
64 }
65
66 unsafe fn send<X: memory::raw::Extent, E: From<Errno>>(
70 file: BorrowedFd<'_>,
71 ptr: *const u8,
72 len: X::Length,
73 ) -> Result<X::Length, E> {
74 let len: bounded::U32<0, { i32::MAX as u32 }> = len.into();
75 let capacity = len.get() as usize;
76 let raw = unsafe { libc::send(file.as_raw_fd(), ptr.cast(), capacity, libc::MSG_NOSIGNAL) };
77 Ok(unsafe {
79 kernel::raw::Status::from_count(raw)
80 .try_count::<E>(|| kernel::raw::Code::last::<Self>().into())
81 }?
82 .bounded()
83 .into())
84 }
85
86 unsafe fn sendmsg<E: From<Errno>>(
90 file: BorrowedFd<'_>,
91 header: &msg::Header,
92 flags: libc::c_int,
93 ) -> Result<bounded::U32<0, { i32::MAX as u32 }>, E> {
94 let raw = unsafe { libc::sendmsg(file.as_raw_fd(), header.as_raw(), flags) };
95 Ok(unsafe {
97 kernel::raw::Status::from_count(raw)
98 .try_count::<E>(|| kernel::raw::Code::last::<Self>().into())
99 }?
100 .bounded())
101 }
102}
103
104impl<T: errno::Source> Source for T {}
105
106pub trait Iovec {
108 unsafe fn as_slice<'a>(&self) -> &'a [u8];
111}
112
113impl Iovec for msg::Iovec {
114 unsafe fn as_slice<'a>(&self) -> &'a [u8] {
115 if self.is_empty() {
116 return &[];
117 }
118 unsafe { slice::from_raw_parts(self.0.iov_base.cast(), self.0.iov_len) }
120 }
121}