1 use crate::io_source::IoSource; 2 use crate::{event, sys, Interest, Registry, Token}; 3 4 use std::fmt; 5 use std::io::{self, IoSlice, IoSliceMut, Read, Write}; 6 use std::net::Shutdown; 7 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; 8 use std::os::unix::net; 9 use std::path::Path; 10 11 /// A non-blocking Unix stream socket. 12 pub struct UnixStream { 13 inner: IoSource<net::UnixStream>, 14 } 15 16 impl UnixStream { 17 /// Connects to the socket named by `path`. connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream>18 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> { 19 sys::uds::stream::connect(path.as_ref()).map(UnixStream::from_std) 20 } 21 22 /// Creates a new `UnixStream` from a standard `net::UnixStream`. 23 /// 24 /// This function is intended to be used to wrap a Unix stream from the 25 /// standard library in the Mio equivalent. The conversion assumes nothing 26 /// about the underlying stream; it is left up to the user to set it in 27 /// non-blocking mode. 28 /// 29 /// # Note 30 /// 31 /// The Unix stream here will not have `connect` called on it, so it 32 /// should already be connected via some other means (be it manually, or 33 /// the standard library). from_std(stream: net::UnixStream) -> UnixStream34 pub fn from_std(stream: net::UnixStream) -> UnixStream { 35 UnixStream { 36 inner: IoSource::new(stream), 37 } 38 } 39 40 /// Creates an unnamed pair of connected sockets. 41 /// 42 /// Returns two `UnixStream`s which are connected to each other. pair() -> io::Result<(UnixStream, UnixStream)>43 pub fn pair() -> io::Result<(UnixStream, UnixStream)> { 44 sys::uds::stream::pair().map(|(stream1, stream2)| { 45 (UnixStream::from_std(stream1), UnixStream::from_std(stream2)) 46 }) 47 } 48 49 /// Returns the socket address of the local half of this connection. local_addr(&self) -> io::Result<sys::SocketAddr>50 pub fn local_addr(&self) -> io::Result<sys::SocketAddr> { 51 sys::uds::stream::local_addr(&self.inner) 52 } 53 54 /// Returns the socket address of the remote half of this connection. peer_addr(&self) -> io::Result<sys::SocketAddr>55 pub fn peer_addr(&self) -> io::Result<sys::SocketAddr> { 56 sys::uds::stream::peer_addr(&self.inner) 57 } 58 59 /// Returns the value of the `SO_ERROR` option. take_error(&self) -> io::Result<Option<io::Error>>60 pub fn take_error(&self) -> io::Result<Option<io::Error>> { 61 self.inner.take_error() 62 } 63 64 /// Shuts down the read, write, or both halves of this connection. 65 /// 66 /// This function will cause all pending and future I/O calls on the 67 /// specified portions to immediately return with an appropriate value 68 /// (see the documentation of `Shutdown`). shutdown(&self, how: Shutdown) -> io::Result<()>69 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { 70 self.inner.shutdown(how) 71 } 72 } 73 74 impl Read for UnixStream { read(&mut self, buf: &mut [u8]) -> io::Result<usize>75 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 76 self.inner.do_io(|inner| (&*inner).read(buf)) 77 } 78 read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>79 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { 80 self.inner.do_io(|inner| (&*inner).read_vectored(bufs)) 81 } 82 } 83 84 impl<'a> Read for &'a UnixStream { read(&mut self, buf: &mut [u8]) -> io::Result<usize>85 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 86 self.inner.do_io(|inner| (&*inner).read(buf)) 87 } 88 read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>89 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { 90 self.inner.do_io(|inner| (&*inner).read_vectored(bufs)) 91 } 92 } 93 94 impl Write for UnixStream { write(&mut self, buf: &[u8]) -> io::Result<usize>95 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 96 self.inner.do_io(|inner| (&*inner).write(buf)) 97 } 98 write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>99 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { 100 self.inner.do_io(|inner| (&*inner).write_vectored(bufs)) 101 } 102 flush(&mut self) -> io::Result<()>103 fn flush(&mut self) -> io::Result<()> { 104 self.inner.do_io(|inner| (&*inner).flush()) 105 } 106 } 107 108 impl<'a> Write for &'a UnixStream { write(&mut self, buf: &[u8]) -> io::Result<usize>109 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 110 self.inner.do_io(|inner| (&*inner).write(buf)) 111 } 112 write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>113 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { 114 self.inner.do_io(|inner| (&*inner).write_vectored(bufs)) 115 } 116 flush(&mut self) -> io::Result<()>117 fn flush(&mut self) -> io::Result<()> { 118 self.inner.do_io(|inner| (&*inner).flush()) 119 } 120 } 121 122 impl event::Source for UnixStream { register( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>123 fn register( 124 &mut self, 125 registry: &Registry, 126 token: Token, 127 interests: Interest, 128 ) -> io::Result<()> { 129 self.inner.register(registry, token, interests) 130 } 131 reregister( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>132 fn reregister( 133 &mut self, 134 registry: &Registry, 135 token: Token, 136 interests: Interest, 137 ) -> io::Result<()> { 138 self.inner.reregister(registry, token, interests) 139 } 140 deregister(&mut self, registry: &Registry) -> io::Result<()>141 fn deregister(&mut self, registry: &Registry) -> io::Result<()> { 142 self.inner.deregister(registry) 143 } 144 } 145 146 impl fmt::Debug for UnixStream { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 148 self.inner.fmt(f) 149 } 150 } 151 152 impl IntoRawFd for UnixStream { into_raw_fd(self) -> RawFd153 fn into_raw_fd(self) -> RawFd { 154 self.inner.into_inner().into_raw_fd() 155 } 156 } 157 158 impl AsRawFd for UnixStream { as_raw_fd(&self) -> RawFd159 fn as_raw_fd(&self) -> RawFd { 160 self.inner.as_raw_fd() 161 } 162 } 163 164 impl FromRawFd for UnixStream { 165 /// Converts a `RawFd` to a `UnixStream`. 166 /// 167 /// # Notes 168 /// 169 /// The caller is responsible for ensuring that the socket is in 170 /// non-blocking mode. from_raw_fd(fd: RawFd) -> UnixStream171 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream { 172 UnixStream::from_std(FromRawFd::from_raw_fd(fd)) 173 } 174 } 175