1use {RecvDgram, SendDgram};
2
3use tokio_reactor::{Handle, PollEvented};
4
5use futures::{Async, Poll};
6use mio::Ready;
7use mio_uds;
8
9use std::fmt;
10use std::io;
11use std::net::Shutdown;
12use std::os::unix::io::{AsRawFd, RawFd};
13use std::os::unix::net::{self, SocketAddr};
14use std::path::Path;
15
16pub struct UnixDatagram {
18 io: PollEvented<mio_uds::UnixDatagram>,
19}
20
21impl UnixDatagram {
22 pub fn bind<P>(path: P) -> io::Result<UnixDatagram>
24 where
25 P: AsRef<Path>,
26 {
27 let socket = mio_uds::UnixDatagram::bind(path)?;
28 Ok(UnixDatagram::new(socket))
29 }
30
31 pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
37 let (a, b) = mio_uds::UnixDatagram::pair()?;
38 let a = UnixDatagram::new(a);
39 let b = UnixDatagram::new(b);
40
41 Ok((a, b))
42 }
43
44 pub fn from_std(datagram: net::UnixDatagram, handle: &Handle) -> io::Result<UnixDatagram> {
50 let socket = mio_uds::UnixDatagram::from_datagram(datagram)?;
51 let io = PollEvented::new_with_handle(socket, handle)?;
52 Ok(UnixDatagram { io })
53 }
54
55 fn new(socket: mio_uds::UnixDatagram) -> UnixDatagram {
56 let io = PollEvented::new(socket);
57 UnixDatagram { io }
58 }
59
60 pub fn unbound() -> io::Result<UnixDatagram> {
62 let socket = mio_uds::UnixDatagram::unbound()?;
63 Ok(UnixDatagram::new(socket))
64 }
65
66 pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
71 self.io.get_ref().connect(path)
72 }
73
74 pub fn poll_read_ready(&self, ready: Ready) -> Poll<Ready, io::Error> {
76 self.io.poll_read_ready(ready)
77 }
78
79 pub fn poll_write_ready(&self) -> Poll<Ready, io::Error> {
81 self.io.poll_write_ready()
82 }
83
84 pub fn local_addr(&self) -> io::Result<SocketAddr> {
86 self.io.get_ref().local_addr()
87 }
88
89 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
93 self.io.get_ref().peer_addr()
94 }
95
96 pub fn poll_recv_from(&self, buf: &mut [u8]) -> Poll<(usize, SocketAddr), io::Error> {
101 try_ready!(self.io.poll_read_ready(Ready::readable()));
102
103 match self.io.get_ref().recv_from(buf) {
104 Ok(ret) => Ok(ret.into()),
105 Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
106 self.io.clear_read_ready(Ready::readable())?;
107 Ok(Async::NotReady)
108 }
109 Err(e) => Err(e),
110 }
111 }
112
113 pub fn poll_recv(&self, buf: &mut [u8]) -> Poll<usize, io::Error> {
117 try_ready!(self.io.poll_read_ready(Ready::readable()));
118
119 match self.io.get_ref().recv(buf) {
120 Ok(ret) => Ok(ret.into()),
121 Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
122 self.io.clear_read_ready(Ready::readable())?;
123 Ok(Async::NotReady)
124 }
125 Err(e) => Err(e),
126 }
127 }
128
129 pub fn recv_dgram<T>(self, buf: T) -> RecvDgram<T>
131 where
132 T: AsMut<[u8]>,
133 {
134 RecvDgram::new(self, buf)
135 }
136
137 pub fn poll_send_to<P>(&self, buf: &[u8], path: P) -> Poll<usize, io::Error>
141 where
142 P: AsRef<Path>,
143 {
144 try_ready!(self.io.poll_write_ready());
145
146 match self.io.get_ref().send_to(buf, path) {
147 Ok(ret) => Ok(ret.into()),
148 Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
149 self.io.clear_write_ready()?;
150 Ok(Async::NotReady)
151 }
152 Err(e) => Err(e),
153 }
154 }
155
156 pub fn poll_send(&self, buf: &[u8]) -> Poll<usize, io::Error> {
163 try_ready!(self.io.poll_write_ready());
164
165 match self.io.get_ref().send(buf) {
166 Ok(ret) => Ok(ret.into()),
167 Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
168 self.io.clear_write_ready()?;
169 Ok(Async::NotReady)
170 }
171 Err(e) => Err(e),
172 }
173 }
174
175 pub fn send_dgram<T, P>(self, buf: T, path: P) -> SendDgram<T, P>
177 where
178 T: AsRef<[u8]>,
179 P: AsRef<Path>,
180 {
181 SendDgram::new(self, buf, path)
182 }
183
184 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
186 self.io.get_ref().take_error()
187 }
188
189 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
195 self.io.get_ref().shutdown(how)
196 }
197}
198
199impl fmt::Debug for UnixDatagram {
200 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
201 self.io.get_ref().fmt(f)
202 }
203}
204
205impl AsRawFd for UnixDatagram {
206 fn as_raw_fd(&self) -> RawFd {
207 self.io.get_ref().as_raw_fd()
208 }
209}