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