1use std::net::{self, SocketAddr};
2#[cfg(any(unix, target_os = "wasi"))]
3use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
4#[cfg(target_os = "hermit")]
7use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
8#[cfg(windows)]
9use std::os::windows::io::{
10 AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
11};
12use std::{fmt, io};
13
14use crate::io_source::IoSource;
15use crate::net::TcpStream;
16#[cfg(any(unix, target_os = "hermit"))]
17use crate::sys::tcp::set_reuseaddr;
18#[cfg(not(target_os = "wasi"))]
19use crate::sys::{
20 tcp::{bind, listen, new_for_addr},
21 LISTEN_BACKLOG_SIZE,
22};
23use crate::{event, sys, Interest, Registry, Token};
24
25#[cfg_attr(feature = "os-poll", doc = "```")]
30#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
31pub struct TcpListener {
52 inner: IoSource<net::TcpListener>,
53}
54
55impl TcpListener {
56 #[cfg(not(target_os = "wasi"))]
66 pub fn bind(addr: SocketAddr) -> io::Result<TcpListener> {
67 let socket = new_for_addr(addr)?;
68 #[cfg(any(unix, target_os = "hermit"))]
69 let listener = unsafe { TcpListener::from_raw_fd(socket) };
70 #[cfg(windows)]
71 let listener = unsafe { TcpListener::from_raw_socket(socket as _) };
72
73 #[cfg(not(windows))]
81 set_reuseaddr(&listener.inner, true)?;
82
83 bind(&listener.inner, addr)?;
84 listen(&listener.inner, LISTEN_BACKLOG_SIZE)?;
85 Ok(listener)
86 }
87
88 pub fn from_std(listener: net::TcpListener) -> TcpListener {
95 TcpListener {
96 inner: IoSource::new(listener),
97 }
98 }
99
100 pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
109 self.inner.do_io(|inner| {
110 sys::tcp::accept(inner).map(|(stream, addr)| (TcpStream::from_std(stream), addr))
111 })
112 }
113
114 pub fn local_addr(&self) -> io::Result<SocketAddr> {
116 self.inner.local_addr()
117 }
118
119 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
124 self.inner.set_ttl(ttl)
125 }
126
127 pub fn ttl(&self) -> io::Result<u32> {
133 self.inner.ttl()
134 }
135
136 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
142 self.inner.take_error()
143 }
144}
145
146impl event::Source for TcpListener {
147 fn register(
148 &mut self,
149 registry: &Registry,
150 token: Token,
151 interests: Interest,
152 ) -> io::Result<()> {
153 self.inner.register(registry, token, interests)
154 }
155
156 fn reregister(
157 &mut self,
158 registry: &Registry,
159 token: Token,
160 interests: Interest,
161 ) -> io::Result<()> {
162 self.inner.reregister(registry, token, interests)
163 }
164
165 fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
166 self.inner.deregister(registry)
167 }
168}
169
170impl fmt::Debug for TcpListener {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 self.inner.fmt(f)
173 }
174}
175
176#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
177impl IntoRawFd for TcpListener {
178 fn into_raw_fd(self) -> RawFd {
179 self.inner.into_inner().into_raw_fd()
180 }
181}
182
183#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
184impl AsRawFd for TcpListener {
185 fn as_raw_fd(&self) -> RawFd {
186 self.inner.as_raw_fd()
187 }
188}
189
190#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
191impl FromRawFd for TcpListener {
192 unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
199 TcpListener::from_std(FromRawFd::from_raw_fd(fd))
200 }
201}
202
203#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
204impl From<TcpListener> for OwnedFd {
205 fn from(tcp_listener: TcpListener) -> Self {
206 tcp_listener.inner.into_inner().into()
207 }
208}
209
210#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
211impl AsFd for TcpListener {
212 fn as_fd(&self) -> BorrowedFd<'_> {
213 self.inner.as_fd()
214 }
215}
216
217#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
218impl From<OwnedFd> for TcpListener {
219 fn from(fd: OwnedFd) -> Self {
226 TcpListener::from_std(From::from(fd))
227 }
228}
229
230#[cfg(windows)]
231impl IntoRawSocket for TcpListener {
232 fn into_raw_socket(self) -> RawSocket {
233 self.inner.into_inner().into_raw_socket()
234 }
235}
236
237#[cfg(windows)]
238impl AsRawSocket for TcpListener {
239 fn as_raw_socket(&self) -> RawSocket {
240 self.inner.as_raw_socket()
241 }
242}
243
244#[cfg(windows)]
245impl FromRawSocket for TcpListener {
246 unsafe fn from_raw_socket(socket: RawSocket) -> TcpListener {
253 TcpListener::from_std(FromRawSocket::from_raw_socket(socket))
254 }
255}
256
257#[cfg(windows)]
258impl From<TcpListener> for OwnedSocket {
259 fn from(tcp_listener: TcpListener) -> Self {
260 tcp_listener.inner.into_inner().into()
261 }
262}
263
264#[cfg(windows)]
265impl AsSocket for TcpListener {
266 fn as_socket(&self) -> BorrowedSocket<'_> {
267 self.inner.as_socket()
268 }
269}
270
271#[cfg(windows)]
272impl From<OwnedSocket> for TcpListener {
273 fn from(socket: OwnedSocket) -> Self {
280 TcpListener::from_std(From::from(socket))
281 }
282}
283
284impl From<TcpListener> for net::TcpListener {
285 fn from(listener: TcpListener) -> Self {
286 unsafe {
290 #[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
291 {
292 net::TcpListener::from_raw_fd(listener.into_raw_fd())
293 }
294 #[cfg(windows)]
295 {
296 net::TcpListener::from_raw_socket(listener.into_raw_socket())
297 }
298 }
299 }
300}