1 use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
2 use std::os::unix::net::{self, SocketAddr};
3 use std::path::Path;
4 use std::{fmt, io};
5 
6 use crate::io_source::IoSource;
7 use crate::net::UnixStream;
8 use crate::{event, sys, Interest, Registry, Token};
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`.
bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener>17     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
18         let addr = SocketAddr::from_pathname(path)?;
19         UnixListener::bind_addr(&addr)
20     }
21 
22     /// Creates a new `UnixListener` bound to the specified socket `address`.
bind_addr(address: &SocketAddr) -> io::Result<UnixListener>23     pub fn bind_addr(address: &SocketAddr) -> io::Result<UnixListener> {
24         sys::uds::listener::bind_addr(address).map(UnixListener::from_std)
25     }
26 
27     /// Creates a new `UnixListener` from a standard `net::UnixListener`.
28     ///
29     /// This function is intended to be used to wrap a Unix listener from the
30     /// standard library in the Mio equivalent. The conversion assumes nothing
31     /// about the underlying listener; it is left up to the user to set it in
32     /// non-blocking mode.
from_std(listener: net::UnixListener) -> UnixListener33     pub fn from_std(listener: net::UnixListener) -> UnixListener {
34         UnixListener {
35             inner: IoSource::new(listener),
36         }
37     }
38 
39     /// Accepts a new incoming connection to this listener.
40     ///
41     /// The call is responsible for ensuring that the listening socket is in
42     /// non-blocking mode.
accept(&self) -> io::Result<(UnixStream, SocketAddr)>43     pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
44         sys::uds::listener::accept(&self.inner)
45     }
46 
47     /// Returns the local socket address of this listener.
local_addr(&self) -> io::Result<SocketAddr>48     pub fn local_addr(&self) -> io::Result<SocketAddr> {
49         self.inner.local_addr()
50     }
51 
52     /// Returns the value of the `SO_ERROR` option.
take_error(&self) -> io::Result<Option<io::Error>>53     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
54         self.inner.take_error()
55     }
56 }
57 
58 impl event::Source for UnixListener {
register( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>59     fn register(
60         &mut self,
61         registry: &Registry,
62         token: Token,
63         interests: Interest,
64     ) -> io::Result<()> {
65         self.inner.register(registry, token, interests)
66     }
67 
reregister( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>68     fn reregister(
69         &mut self,
70         registry: &Registry,
71         token: Token,
72         interests: Interest,
73     ) -> io::Result<()> {
74         self.inner.reregister(registry, token, interests)
75     }
76 
deregister(&mut self, registry: &Registry) -> io::Result<()>77     fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
78         self.inner.deregister(registry)
79     }
80 }
81 
82 impl fmt::Debug for UnixListener {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result83     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84         self.inner.fmt(f)
85     }
86 }
87 
88 impl IntoRawFd for UnixListener {
into_raw_fd(self) -> RawFd89     fn into_raw_fd(self) -> RawFd {
90         self.inner.into_inner().into_raw_fd()
91     }
92 }
93 
94 impl AsRawFd for UnixListener {
as_raw_fd(&self) -> RawFd95     fn as_raw_fd(&self) -> RawFd {
96         self.inner.as_raw_fd()
97     }
98 }
99 
100 impl FromRawFd for UnixListener {
101     /// Converts a `RawFd` to a `UnixListener`.
102     ///
103     /// # Notes
104     ///
105     /// The caller is responsible for ensuring that the socket is in
106     /// non-blocking mode.
from_raw_fd(fd: RawFd) -> UnixListener107     unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
108         UnixListener::from_std(FromRawFd::from_raw_fd(fd))
109     }
110 }
111 
112 impl From<UnixListener> for net::UnixListener {
from(listener: UnixListener) -> Self113     fn from(listener: UnixListener) -> Self {
114         // Safety: This is safe since we are extracting the raw fd from a well-constructed
115         // mio::net::uds::UnixListener which ensures that we actually pass in a valid file
116         // descriptor/socket
117         unsafe { net::UnixListener::from_raw_fd(listener.into_raw_fd()) }
118     }
119 }
120 
121 impl From<UnixListener> for OwnedFd {
from(unix_listener: UnixListener) -> Self122     fn from(unix_listener: UnixListener) -> Self {
123         unix_listener.inner.into_inner().into()
124     }
125 }
126 
127 impl AsFd for UnixListener {
as_fd(&self) -> BorrowedFd<'_>128     fn as_fd(&self) -> BorrowedFd<'_> {
129         self.inner.as_fd()
130     }
131 }
132 
133 impl From<OwnedFd> for UnixListener {
from(fd: OwnedFd) -> Self134     fn from(fd: OwnedFd) -> Self {
135         UnixListener::from_std(From::from(fd))
136     }
137 }
138