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};
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(&self, output: buffer::raw::Output<'_>) -> Result<Option<()>, Errno>;
22
23 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 unsafe fn accept(
38 &self,
39 addr: *mut libc::sockaddr_storage,
40 len: *mut socklen_t,
41 ) -> Result<Self, accept::Error>;
42}
43
44pub trait Source: errno::Source {
46 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 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 Ok(
71 unsafe { kernel::raw::Status::from_count(raw).try_count::<Self, E>() }?
72 .bounded()
73 .into(),
74 )
75 }
76
77 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 Ok(unsafe { kernel::raw::Status::from_count(raw).try_count::<Self, E>() }?.bounded())
88 }
89}
90
91impl<T: errno::Source> Source for T {}
92
93pub trait Iovec {
95 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 unsafe { slice::from_raw_parts(self.0.iov_base.cast(), self.0.iov_len) }
107 }
108}