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