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