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(
17 unix,
18 target_os = "hermit",
19 all(target_os = "wasi", not(target_env = "p1"))
20))]
21use crate::sys::tcp::set_reuseaddr;
22#[cfg(not(all(target_os = "wasi", target_env = "p1")))]
23use crate::sys::tcp::{bind, listen, new_for_addr};
24use crate::{event, sys, Interest, Registry, Token};
25
26#[cfg_attr(feature = "os-poll", doc = "```")]
31#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
32pub struct TcpListener {
53 inner: IoSource<net::TcpListener>,
54}
55
56impl TcpListener {
57 #[cfg(not(all(target_os = "wasi", target_env = "p1")))]
67 pub fn bind(addr: SocketAddr) -> io::Result<TcpListener> {
68 let socket = new_for_addr(addr)?;
69 #[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
70 let listener = unsafe { TcpListener::from_raw_fd(socket) };
71 #[cfg(windows)]
72 let listener = unsafe { TcpListener::from_raw_socket(socket as _) };
73
74 #[cfg(not(windows))]
82 set_reuseaddr(&listener.inner, true)?;
83
84 bind(&listener.inner, addr)?;
85 let backlog = if cfg!(target_os = "horizon") {
88 20
89 } else if cfg!(target_os = "haiku") {
90 32
91 } else {
92 128
93 };
94 listen(&listener.inner, backlog)?;
95 Ok(listener)
96 }
97
98 pub fn from_std(listener: net::TcpListener) -> TcpListener {
105 TcpListener {
106 inner: IoSource::new(listener),
107 }
108 }
109
110 pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
119 self.inner.do_io(|inner| {
120 sys::tcp::accept(inner).map(|(stream, addr)| (TcpStream::from_std(stream), addr))
121 })
122 }
123
124 pub fn local_addr(&self) -> io::Result<SocketAddr> {
126 self.inner.local_addr()
127 }
128
129 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
134 self.inner.set_ttl(ttl)
135 }
136
137 pub fn ttl(&self) -> io::Result<u32> {
143 self.inner.ttl()
144 }
145
146 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
152 self.inner.take_error()
153 }
154}
155
156impl event::Source for TcpListener {
157 fn register(
158 &mut self,
159 registry: &Registry,
160 token: Token,
161 interests: Interest,
162 ) -> io::Result<()> {
163 self.inner.register(registry, token, interests)
164 }
165
166 fn reregister(
167 &mut self,
168 registry: &Registry,
169 token: Token,
170 interests: Interest,
171 ) -> io::Result<()> {
172 self.inner.reregister(registry, token, interests)
173 }
174
175 fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
176 self.inner.deregister(registry)
177 }
178}
179
180impl fmt::Debug for TcpListener {
181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 self.inner.fmt(f)
183 }
184}
185
186#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
187impl IntoRawFd for TcpListener {
188 fn into_raw_fd(self) -> RawFd {
189 self.inner.into_inner().into_raw_fd()
190 }
191}
192
193#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
194impl AsRawFd for TcpListener {
195 fn as_raw_fd(&self) -> RawFd {
196 self.inner.as_raw_fd()
197 }
198}
199
200#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
201impl FromRawFd for TcpListener {
202 unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
209 TcpListener::from_std(FromRawFd::from_raw_fd(fd))
210 }
211}
212
213#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
214impl From<TcpListener> for OwnedFd {
215 fn from(tcp_listener: TcpListener) -> Self {
216 tcp_listener.inner.into_inner().into()
217 }
218}
219
220#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
221impl AsFd for TcpListener {
222 fn as_fd(&self) -> BorrowedFd<'_> {
223 self.inner.as_fd()
224 }
225}
226
227#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
228impl From<OwnedFd> for TcpListener {
229 fn from(fd: OwnedFd) -> Self {
236 TcpListener::from_std(From::from(fd))
237 }
238}
239
240#[cfg(windows)]
241impl IntoRawSocket for TcpListener {
242 fn into_raw_socket(self) -> RawSocket {
243 self.inner.into_inner().into_raw_socket()
244 }
245}
246
247#[cfg(windows)]
248impl AsRawSocket for TcpListener {
249 fn as_raw_socket(&self) -> RawSocket {
250 self.inner.as_raw_socket()
251 }
252}
253
254#[cfg(windows)]
255impl FromRawSocket for TcpListener {
256 unsafe fn from_raw_socket(socket: RawSocket) -> TcpListener {
263 TcpListener::from_std(FromRawSocket::from_raw_socket(socket))
264 }
265}
266
267#[cfg(windows)]
268impl From<TcpListener> for OwnedSocket {
269 fn from(tcp_listener: TcpListener) -> Self {
270 tcp_listener.inner.into_inner().into()
271 }
272}
273
274#[cfg(windows)]
275impl AsSocket for TcpListener {
276 fn as_socket(&self) -> BorrowedSocket<'_> {
277 self.inner.as_socket()
278 }
279}
280
281#[cfg(windows)]
282impl From<OwnedSocket> for TcpListener {
283 fn from(socket: OwnedSocket) -> Self {
290 TcpListener::from_std(From::from(socket))
291 }
292}
293
294impl From<TcpListener> for net::TcpListener {
295 fn from(listener: TcpListener) -> Self {
296 unsafe {
300 #[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
301 {
302 net::TcpListener::from_raw_fd(listener.into_raw_fd())
303 }
304 #[cfg(windows)]
305 {
306 net::TcpListener::from_raw_socket(listener.into_raw_socket())
307 }
308 }
309 }
310}