1use std::io;
2use std::net::Shutdown;
3use std::os::unix::net;
4use std::os::unix::prelude::*;
5use std::path::Path;
6
7use libc;
8use mio::event::Evented;
9use mio::unix::EventedFd;
10use mio::{Poll, Token, Ready, PollOpt};
11
12use cvt;
13use socket::{sockaddr_un, Socket};
14
15#[derive(Debug)]
17pub struct UnixDatagram {
18 inner: net::UnixDatagram,
19}
20
21impl UnixDatagram {
22 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
24 UnixDatagram::_bind(path.as_ref())
25 }
26
27 fn _bind(path: &Path) -> io::Result<UnixDatagram> {
28 unsafe {
29 let (addr, len) = try!(sockaddr_un(path));
30 let fd = try!(Socket::new(libc::SOCK_DGRAM));
31
32 let addr = &addr as *const _ as *const _;
33 try!(cvt(libc::bind(fd.fd(), addr, len)));
34
35 Ok(UnixDatagram::from_raw_fd(fd.into_fd()))
36 }
37 }
38
39 pub fn from_datagram(stream: net::UnixDatagram) -> io::Result<UnixDatagram> {
45 try!(stream.set_nonblocking(true));
46 Ok(UnixDatagram { inner: stream })
47 }
48
49 pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
53 unsafe {
54 let (a, b) = try!(Socket::pair(libc::SOCK_DGRAM));
55 Ok((UnixDatagram::from_raw_fd(a.into_fd()),
56 UnixDatagram::from_raw_fd(b.into_fd())))
57 }
58 }
59
60 pub fn unbound() -> io::Result<UnixDatagram> {
62 let stream = try!(net::UnixDatagram::unbound());
63 try!(stream.set_nonblocking(true));
64 Ok(UnixDatagram { inner: stream })
65 }
66
67 pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
72 self.inner.connect(path)
73 }
74
75 pub fn try_clone(&self) -> io::Result<UnixDatagram> {
81 self.inner.try_clone().map(|i| {
82 UnixDatagram { inner: i }
83 })
84 }
85
86 pub fn local_addr(&self) -> io::Result<net::SocketAddr> {
88 self.inner.local_addr()
89 }
90
91 pub fn peer_addr(&self) -> io::Result<net::SocketAddr> {
95 self.inner.peer_addr()
96 }
97
98 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, net::SocketAddr)> {
103 self.inner.recv_from(buf)
104 }
105
106 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
110 self.inner.recv(buf)
111 }
112
113 pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
117 self.inner.send_to(buf, path)
118 }
119
120 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
127 self.inner.send(buf)
128 }
129
130 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
132 self.inner.take_error()
133 }
134
135 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
141 self.inner.shutdown(how)
142 }
143}
144
145impl Evented for UnixDatagram {
146 fn register(&self,
147 poll: &Poll,
148 token: Token,
149 events: Ready,
150 opts: PollOpt) -> io::Result<()> {
151 EventedFd(&self.as_raw_fd()).register(poll, token, events, opts)
152 }
153
154 fn reregister(&self,
155 poll: &Poll,
156 token: Token,
157 events: Ready,
158 opts: PollOpt) -> io::Result<()> {
159 EventedFd(&self.as_raw_fd()).reregister(poll, token, events, opts)
160 }
161
162 fn deregister(&self, poll: &Poll) -> io::Result<()> {
163 EventedFd(&self.as_raw_fd()).deregister(poll)
164 }
165}
166
167impl AsRawFd for UnixDatagram {
168 fn as_raw_fd(&self) -> i32 {
169 self.inner.as_raw_fd()
170 }
171}
172
173impl IntoRawFd for UnixDatagram {
174 fn into_raw_fd(self) -> i32 {
175 self.inner.into_raw_fd()
176 }
177}
178
179impl FromRawFd for UnixDatagram {
180 unsafe fn from_raw_fd(fd: i32) -> UnixDatagram {
181 UnixDatagram { inner: net::UnixDatagram::from_raw_fd(fd) }
182 }
183}