tokio_seqpacket/
listener.rs1use filedesc::FileDesc;
2use std::os::raw::c_int;
3use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, IntoRawFd, OwnedFd};
4use std::path::{Path, PathBuf};
5use std::task::{Context, Poll};
6use tokio::io::unix::AsyncFd;
7
8use crate::{sys, UnixSeqpacket};
9
10pub struct UnixSeqpacketListener {
12 io: AsyncFd<FileDesc>,
13}
14
15impl std::fmt::Debug for UnixSeqpacketListener {
16 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
17 f.debug_struct("UnixSeqpacketListener")
18 .field("fd", &self.io.get_ref().as_raw_fd())
19 .finish()
20 }
21}
22
23impl AsFd for UnixSeqpacketListener {
24 fn as_fd(&self) -> BorrowedFd<'_> {
25 self.io.get_ref().as_fd()
26 }
27}
28
29impl TryFrom<OwnedFd> for UnixSeqpacketListener {
30 type Error = std::io::Error;
31
32 fn try_from(fd: OwnedFd) -> Result<Self, Self::Error> {
33 Self::new(FileDesc::new(fd))
34 }
35}
36
37impl From<UnixSeqpacketListener> for OwnedFd {
38 fn from(socket: UnixSeqpacketListener) -> Self {
39 socket.io.into_inner().into_fd()
40 }
41}
42
43impl UnixSeqpacketListener {
44 fn new(socket: FileDesc) -> std::io::Result<Self> {
45 let io = AsyncFd::new(socket)?;
46 Ok(Self { io })
47 }
48
49 pub fn bind<P: AsRef<Path>>(address: P) -> std::io::Result<Self> {
53 Self::bind_with_backlog(address, 128)
54 }
55
56 pub fn bind_with_backlog<P: AsRef<Path>>(address: P, backlog: c_int) -> std::io::Result<Self> {
63 let socket = sys::local_seqpacket_socket()?;
64 sys::bind(&socket, address)?;
65 sys::listen(&socket, backlog)?;
66 Self::new(socket)
67 }
68
69 pub unsafe fn from_raw_fd(fd: std::os::unix::io::RawFd) -> std::io::Result<Self> {
79 Self::new(FileDesc::from_raw_fd(fd))
80 }
81
82 pub fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
84 self.io.as_raw_fd()
85 }
86
87 pub fn into_raw_fd(self) -> std::os::unix::io::RawFd {
89 self.io.into_inner().into_raw_fd()
90 }
91
92 pub fn local_addr(&self) -> std::io::Result<PathBuf> {
94 sys::get_local_address(self.io.get_ref())
95 }
96
97 pub fn take_error(&self) -> std::io::Result<Option<std::io::Error>> {
99 sys::take_socket_error(self.io.get_ref())
100 }
101
102 pub fn poll_accept(&mut self, cx: &mut Context) -> Poll<std::io::Result<UnixSeqpacket>> {
110 let socket = loop {
111 let mut ready_guard = ready!(self.io.poll_read_ready(cx)?);
112
113 match ready_guard.try_io(|inner| sys::accept(inner.get_ref())) {
114 Ok(x) => break x?,
115 Err(_would_block) => continue,
116 }
117 };
118
119 Poll::Ready(Ok(UnixSeqpacket::new(socket)?))
120 }
121
122 pub async fn accept(&mut self) -> std::io::Result<UnixSeqpacket> {
130 let socket = loop {
131 let mut ready_guard = self.io.readable().await?;
132
133 match ready_guard.try_io(|inner| sys::accept(inner.get_ref())) {
134 Ok(x) => break x?,
135 Err(_would_block) => continue,
136 }
137 };
138
139 UnixSeqpacket::new(socket)
140 }
141}
142
143impl AsRawFd for UnixSeqpacketListener {
144 fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
145 self.as_raw_fd()
146 }
147}
148
149impl IntoRawFd for UnixSeqpacketListener {
150 fn into_raw_fd(self) -> std::os::unix::io::RawFd {
151 self.into_raw_fd()
152 }
153}