monoio/net/unix/seq_packet/
listener.rs

1use std::{
2    io,
3    os::fd::{AsRawFd, RawFd},
4    path::Path,
5};
6
7use super::UnixSeqpacket;
8use crate::{
9    driver::{op::Op, shared_fd::SharedFd},
10    io::stream::Stream,
11    net::{
12        new_socket,
13        unix::{socket_addr::socket_addr, SocketAddr},
14    },
15};
16
17const DEFAULT_BACKLOG: libc::c_int = 128;
18
19/// Listener for UnixSeqpacket
20pub struct UnixSeqpacketListener {
21    fd: SharedFd,
22}
23
24impl UnixSeqpacketListener {
25    /// Creates a new `UnixSeqpacketListener` bound to the specified path with custom backlog
26    pub fn bind_with_backlog<P: AsRef<Path>>(path: P, backlog: libc::c_int) -> io::Result<Self> {
27        let (addr, addr_len) = socket_addr(path.as_ref())?;
28        let socket = new_socket(libc::AF_UNIX, libc::SOCK_SEQPACKET)?;
29        crate::syscall!(bind@RAW(socket, &addr as *const _ as *const _, addr_len))?;
30        crate::syscall!(listen@RAW(socket, backlog))?;
31        Ok(Self {
32            fd: SharedFd::new::<false>(socket)?,
33        })
34    }
35
36    /// Creates a new `UnixSeqpacketListener` bound to the specified path with default backlog(128)
37    #[inline]
38    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<Self> {
39        Self::bind_with_backlog(path, DEFAULT_BACKLOG)
40    }
41
42    /// Accept a UnixSeqpacket
43    pub async fn accept(&self) -> io::Result<(UnixSeqpacket, SocketAddr)> {
44        let op = Op::accept(&self.fd)?;
45
46        // Await the completion of the event
47        let completion = op.await;
48
49        // Convert fd
50        let fd = completion.meta.result?;
51
52        // Construct stream
53        let stream = UnixSeqpacket::from_shared_fd(SharedFd::new::<false>(fd.into_inner() as _)?);
54
55        // Construct SocketAddr
56        let mut storage = unsafe { std::mem::MaybeUninit::assume_init(completion.data.addr.0) };
57        let storage: *mut libc::sockaddr_storage = &mut storage as *mut _;
58        let raw_addr_un: libc::sockaddr_un = unsafe { *storage.cast() };
59        let raw_addr_len = completion.data.addr.1;
60
61        let addr = SocketAddr::from_parts(raw_addr_un, raw_addr_len);
62
63        Ok((stream, addr))
64    }
65}
66
67impl AsRawFd for UnixSeqpacketListener {
68    #[inline]
69    fn as_raw_fd(&self) -> RawFd {
70        self.fd.raw_fd()
71    }
72}
73
74impl std::fmt::Debug for UnixSeqpacketListener {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        f.debug_struct("UnixSeqpacketListener")
77            .field("fd", &self.fd)
78            .finish()
79    }
80}
81
82impl Stream for UnixSeqpacketListener {
83    type Item = io::Result<(UnixSeqpacket, SocketAddr)>;
84
85    #[inline]
86    async fn next(&mut self) -> Option<Self::Item> {
87        Some(self.accept().await)
88    }
89}