1 | use crate::io_source::IoSource; |
2 | use crate::net::{SocketAddr, UnixStream}; |
3 | use crate::{event, sys, Interest, Registry, Token}; |
4 | |
5 | use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; |
6 | use std::os::unix::net; |
7 | use std::path::Path; |
8 | use std::{fmt, io}; |
9 | |
10 | /// A non-blocking Unix domain socket server. |
11 | pub struct UnixListener { |
12 | inner: IoSource<net::UnixListener>, |
13 | } |
14 | |
15 | impl UnixListener { |
16 | /// Creates a new `UnixListener` bound to the specified socket. |
17 | pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> { |
18 | sys::uds::listener::bind(path.as_ref()).map(UnixListener::from_std) |
19 | } |
20 | |
21 | /// Creates a new `UnixListener` from a standard `net::UnixListener`. |
22 | /// |
23 | /// This function is intended to be used to wrap a Unix listener from the |
24 | /// standard library in the Mio equivalent. The conversion assumes nothing |
25 | /// about the underlying listener; it is left up to the user to set it in |
26 | /// non-blocking mode. |
27 | pub fn from_std(listener: net::UnixListener) -> UnixListener { |
28 | UnixListener { |
29 | inner: IoSource::new(listener), |
30 | } |
31 | } |
32 | |
33 | /// Accepts a new incoming connection to this listener. |
34 | /// |
35 | /// The call is responsible for ensuring that the listening socket is in |
36 | /// non-blocking mode. |
37 | pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { |
38 | sys::uds::listener::accept(&self.inner) |
39 | } |
40 | |
41 | /// Returns the local socket address of this listener. |
42 | pub fn local_addr(&self) -> io::Result<sys::SocketAddr> { |
43 | sys::uds::listener::local_addr(&self.inner) |
44 | } |
45 | |
46 | /// Returns the value of the `SO_ERROR` option. |
47 | pub fn take_error(&self) -> io::Result<Option<io::Error>> { |
48 | self.inner.take_error() |
49 | } |
50 | } |
51 | |
52 | impl event::Source for UnixListener { |
53 | fn register( |
54 | &mut self, |
55 | registry: &Registry, |
56 | token: Token, |
57 | interests: Interest, |
58 | ) -> io::Result<()> { |
59 | self.inner.register(registry, token, interests) |
60 | } |
61 | |
62 | fn reregister( |
63 | &mut self, |
64 | registry: &Registry, |
65 | token: Token, |
66 | interests: Interest, |
67 | ) -> io::Result<()> { |
68 | self.inner.reregister(registry, token, interests) |
69 | } |
70 | |
71 | fn deregister(&mut self, registry: &Registry) -> io::Result<()> { |
72 | self.inner.deregister(registry) |
73 | } |
74 | } |
75 | |
76 | impl fmt::Debug for UnixListener { |
77 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
78 | self.inner.fmt(f) |
79 | } |
80 | } |
81 | |
82 | impl IntoRawFd for UnixListener { |
83 | fn into_raw_fd(self) -> RawFd { |
84 | self.inner.into_inner().into_raw_fd() |
85 | } |
86 | } |
87 | |
88 | impl AsRawFd for UnixListener { |
89 | fn as_raw_fd(&self) -> RawFd { |
90 | self.inner.as_raw_fd() |
91 | } |
92 | } |
93 | |
94 | impl FromRawFd for UnixListener { |
95 | /// Converts a `RawFd` to a `UnixListener`. |
96 | /// |
97 | /// # Notes |
98 | /// |
99 | /// The caller is responsible for ensuring that the socket is in |
100 | /// non-blocking mode. |
101 | unsafe fn from_raw_fd(fd: RawFd) -> UnixListener { |
102 | UnixListener::from_std(listener:FromRawFd::from_raw_fd(fd)) |
103 | } |
104 | } |
105 | |