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::tcp::{bind, listen, new_for_addr};
20use crate::{event, sys, Interest, Registry, Token};
21
22#[cfg_attr(feature = "os-poll", doc = "```")]
27#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
28pub struct TcpListener {
49 inner: IoSource<net::TcpListener>,
50}
51
52impl TcpListener {
53 #[cfg(not(target_os = "wasi"))]
63 pub fn bind(addr: SocketAddr) -> io::Result<TcpListener> {
64 let socket = new_for_addr(addr)?;
65 #[cfg(any(unix, target_os = "hermit"))]
66 let listener = unsafe { TcpListener::from_raw_fd(socket) };
67 #[cfg(windows)]
68 let listener = unsafe { TcpListener::from_raw_socket(socket as _) };
69
70 #[cfg(not(windows))]
78 set_reuseaddr(&listener.inner, true)?;
79
80 bind(&listener.inner, addr)?;
81 listen(&listener.inner, 1024)?;
82 Ok(listener)
83 }
84
85 pub fn from_std(listener: net::TcpListener) -> TcpListener {
92 TcpListener {
93 inner: IoSource::new(listener),
94 }
95 }
96
97 pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
106 self.inner.do_io(|inner| {
107 sys::tcp::accept(inner).map(|(stream, addr)| (TcpStream::from_std(stream), addr))
108 })
109 }
110
111 pub fn local_addr(&self) -> io::Result<SocketAddr> {
113 self.inner.local_addr()
114 }
115
116 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
121 self.inner.set_ttl(ttl)
122 }
123
124 pub fn ttl(&self) -> io::Result<u32> {
130 self.inner.ttl()
131 }
132
133 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
139 self.inner.take_error()
140 }
141}
142
143impl event::Source for TcpListener {
144 fn register(
145 &mut self,
146 registry: &Registry,
147 token: Token,
148 interests: Interest,
149 ) -> io::Result<()> {
150 self.inner.register(registry, token, interests)
151 }
152
153 fn reregister(
154 &mut self,
155 registry: &Registry,
156 token: Token,
157 interests: Interest,
158 ) -> io::Result<()> {
159 self.inner.reregister(registry, token, interests)
160 }
161
162 fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
163 self.inner.deregister(registry)
164 }
165}
166
167impl fmt::Debug for TcpListener {
168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169 self.inner.fmt(f)
170 }
171}
172
173#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
174impl IntoRawFd for TcpListener {
175 fn into_raw_fd(self) -> RawFd {
176 self.inner.into_inner().into_raw_fd()
177 }
178}
179
180#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
181impl AsRawFd for TcpListener {
182 fn as_raw_fd(&self) -> RawFd {
183 self.inner.as_raw_fd()
184 }
185}
186
187#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
188impl FromRawFd for TcpListener {
189 unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
196 TcpListener::from_std(FromRawFd::from_raw_fd(fd))
197 }
198}
199
200#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
201impl From<TcpListener> for OwnedFd {
202 fn from(tcp_listener: TcpListener) -> Self {
203 tcp_listener.inner.into_inner().into()
204 }
205}
206
207#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
208impl AsFd for TcpListener {
209 fn as_fd(&self) -> BorrowedFd<'_> {
210 self.inner.as_fd()
211 }
212}
213
214#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
215impl From<OwnedFd> for TcpListener {
216 fn from(fd: OwnedFd) -> Self {
223 TcpListener::from_std(From::from(fd))
224 }
225}
226
227#[cfg(windows)]
228impl IntoRawSocket for TcpListener {
229 fn into_raw_socket(self) -> RawSocket {
230 self.inner.into_inner().into_raw_socket()
231 }
232}
233
234#[cfg(windows)]
235impl AsRawSocket for TcpListener {
236 fn as_raw_socket(&self) -> RawSocket {
237 self.inner.as_raw_socket()
238 }
239}
240
241#[cfg(windows)]
242impl FromRawSocket for TcpListener {
243 unsafe fn from_raw_socket(socket: RawSocket) -> TcpListener {
250 TcpListener::from_std(FromRawSocket::from_raw_socket(socket))
251 }
252}
253
254#[cfg(windows)]
255impl From<TcpListener> for OwnedSocket {
256 fn from(tcp_listener: TcpListener) -> Self {
257 tcp_listener.inner.into_inner().into()
258 }
259}
260
261#[cfg(windows)]
262impl AsSocket for TcpListener {
263 fn as_socket(&self) -> BorrowedSocket<'_> {
264 self.inner.as_socket()
265 }
266}
267
268#[cfg(windows)]
269impl From<OwnedSocket> for TcpListener {
270 fn from(socket: OwnedSocket) -> Self {
277 TcpListener::from_std(From::from(socket))
278 }
279}
280
281impl From<TcpListener> for net::TcpListener {
282 fn from(listener: TcpListener) -> Self {
283 unsafe {
287 #[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
288 {
289 net::TcpListener::from_raw_fd(listener.into_raw_fd())
290 }
291 #[cfg(windows)]
292 {
293 net::TcpListener::from_raw_socket(listener.into_raw_socket())
294 }
295 }
296 }
297}