monoio/net/unix/datagram/
mod.rs1use std::{
4 io,
5 os::unix::{
6 net::UnixDatagram as StdUnixDatagram,
7 prelude::{AsRawFd, IntoRawFd, RawFd},
8 },
9 path::Path,
10};
11
12use super::{
13 socket_addr::{local_addr, pair, peer_addr, socket_addr},
14 SocketAddr,
15};
16use crate::{
17 buf::{IoBuf, IoBufMut},
18 driver::{op::Op, shared_fd::SharedFd},
19 net::new_socket,
20};
21
22pub struct UnixDatagram {
24 fd: SharedFd,
25}
26
27impl UnixDatagram {
28 pub(crate) fn from_shared_fd(fd: SharedFd) -> Self {
29 Self { fd }
30 }
31
32 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<Self> {
34 StdUnixDatagram::bind(path).and_then(Self::from_std)
35 }
36
37 pub fn unbound() -> io::Result<Self> {
39 StdUnixDatagram::unbound().and_then(Self::from_std)
40 }
41
42 pub fn pair() -> io::Result<(Self, Self)> {
44 let (a, b) = pair(libc::SOCK_DGRAM)?;
45 Ok((Self::from_std(a)?, Self::from_std(b)?))
46 }
47
48 pub async fn connect<P: AsRef<Path>>(path: P) -> io::Result<Self> {
50 let (addr, addr_len) = socket_addr(path.as_ref())?;
51 Self::inner_connect(addr, addr_len).await
52 }
53
54 pub async fn connect_addr(addr: SocketAddr) -> io::Result<Self> {
56 let (addr, addr_len) = addr.into_parts();
57 Self::inner_connect(addr, addr_len).await
58 }
59
60 #[inline(always)]
61 async fn inner_connect(
62 sockaddr: libc::sockaddr_un,
63 socklen: libc::socklen_t,
64 ) -> io::Result<Self> {
65 let socket = new_socket(libc::AF_UNIX, libc::SOCK_DGRAM)?;
66 let op = Op::connect_unix(SharedFd::new::<false>(socket)?, sockaddr, socklen)?;
67 let completion = op.await;
68 completion.meta.result?;
69
70 Ok(Self::from_shared_fd(completion.data.fd))
71 }
72
73 pub fn from_std(datagram: StdUnixDatagram) -> io::Result<Self> {
75 match SharedFd::new::<false>(datagram.as_raw_fd()) {
76 Ok(shared) => {
77 let _ = datagram.into_raw_fd();
78 Ok(Self::from_shared_fd(shared))
79 }
80 Err(e) => Err(e),
81 }
82 }
83
84 pub fn local_addr(&self) -> io::Result<SocketAddr> {
86 local_addr(self.as_raw_fd())
87 }
88
89 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
91 peer_addr(self.as_raw_fd())
92 }
93
94 pub async fn readable(&self, relaxed: bool) -> io::Result<()> {
105 let op = Op::poll_read(&self.fd, relaxed).unwrap();
106 op.wait().await
107 }
108
109 pub async fn writable(&self, relaxed: bool) -> io::Result<()> {
120 let op = Op::poll_write(&self.fd, relaxed).unwrap();
121 op.wait().await
122 }
123
124 pub async fn send_to<T: IoBuf, P: AsRef<Path>>(
127 &self,
128 buf: T,
129 path: P,
130 ) -> crate::BufResult<usize, T> {
131 let addr = match crate::net::unix::socket_addr::socket_addr(path.as_ref()) {
132 Ok(addr) => addr,
133 Err(e) => return (Err(e), buf),
134 };
135 let op = Op::send_msg_unix(
136 self.fd.clone(),
137 buf,
138 Some(SocketAddr::from_parts(addr.0, addr.1)),
139 )
140 .unwrap();
141 op.wait().await
142 }
143
144 pub async fn recv_from<T: IoBufMut>(&self, buf: T) -> crate::BufResult<(usize, SocketAddr), T> {
147 let op = Op::recv_msg_unix(self.fd.clone(), buf).unwrap();
148 op.wait().await
149 }
150
151 pub async fn send<T: IoBuf>(&self, buf: T) -> crate::BufResult<usize, T> {
153 let op = Op::send_msg_unix(self.fd.clone(), buf, None).unwrap();
154 op.wait().await
155 }
156
157 pub async fn recv<T: IoBufMut>(&self, buf: T) -> crate::BufResult<usize, T> {
160 let op = Op::recv(self.fd.clone(), buf).unwrap();
161 op.result().await
162 }
163}
164
165impl AsRawFd for UnixDatagram {
166 #[inline]
167 fn as_raw_fd(&self) -> RawFd {
168 self.fd.raw_fd()
169 }
170}
171
172impl std::fmt::Debug for UnixDatagram {
173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 f.debug_struct("UnixDatagram")
175 .field("fd", &self.fd)
176 .finish()
177 }
178}