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`. 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). 34 pub fn from_std(stream: net::UnixStream) -> UnixStream { 35 UnixStream { 36 inner: IoSource::new(stream), 37 } 38 } 39 hmac_expkey(akmos_algo_id algo,const uint8_t * key,size_t len,uint8_t * ekey)40 /// Creates an unnamed pair of connected sockets. 41 /// 42 /// Returns two `UnixStream`s which are connected to each other. 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. 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. akmos_hmac_init(akmos_mac_mode_t * uctx,akmos_algo_id algo)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. 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`). 69 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { 70 self.inner.shutdown(how) 71 } 72 } 73 74 impl Read for UnixStream { 75 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 76 self.inner.do_io(|inner| (&*inner).read(buf)) 77 } 78 akmos_hmac_setkey(akmos_mac_mode_t * uctx,const uint8_t * key,size_t len)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 { 85 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 86 self.inner.do_io(|inner| (&*inner).read(buf)) 87 } 88 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 { 95 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 96 self.inner.do_io(|inner| (&*inner).write(buf)) 97 } 98 99 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { 100 self.inner.do_io(|inner| (&*inner).write_vectored(bufs)) 101 } 102 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 { 109 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 110 self.inner.do_io(|inner| (&*inner).write(buf)) 111 } 112 113 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { 114 self.inner.do_io(|inner| (&*inner).write_vectored(bufs)) 115 } 116 117 fn flush(&mut self) -> io::Result<()> { 118 self.inner.do_io(|inner| (&*inner).flush()) 119 } 120 } 121 122 impl event::Source for UnixStream { 123 fn register( 124 &mut self, 125 registry: &Registry, 126 token: Token, 127 interests: Interest, akmos_hmac_update(akmos_mac_mode_t * uctx,const uint8_t * blk,size_t len)128 ) -> io::Result<()> { 129 self.inner.register(registry, token, interests) 130 } 131 132 fn reregister( 133 &mut self, 134 registry: &Registry, 135 token: Token, 136 interests: Interest, akmos_hmac_done(akmos_mac_mode_t * uctx,uint8_t * mac)137 ) -> io::Result<()> { 138 self.inner.reregister(registry, token, interests) 139 } 140 141 fn deregister(&mut self, registry: &Registry) -> io::Result<()> { 142 self.inner.deregister(registry) 143 } 144 } 145 146 impl fmt::Debug for UnixStream { 147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 148 self.inner.fmt(f) 149 } 150 } 151 152 impl IntoRawFd for UnixStream { 153 fn into_raw_fd(self) -> RawFd { 154 self.inner.into_inner().into_raw_fd() 155 } 156 } 157 158 impl AsRawFd for UnixStream { 159 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. 171 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream { 172 UnixStream::from_std(FromRawFd::from_raw_fd(fd)) 173 } 174 } 175