asyncio/
seq_packet_socket.rs

1use prelude::{Protocol, IoControl, GetSocketOption, SetSocketOption};
2use ffi::{RawFd, AsRawFd, ioctl, getsockopt, setsockopt,
3          getsockname, getpeername, socket, bind, shutdown};
4use core::{IoContext, AsIoContext, Socket, AsyncFd};
5use async::Handler;
6use socket_base::{Shutdown, BytesReadable};
7use reactive_io::{AsAsyncFd, getnonblock, setnonblock, cancel, connect, async_connect,
8                  send, async_send, recv, async_recv};
9
10use std::io;
11use std::fmt;
12
13/// Provides a sequenced packet socket.
14pub struct SeqPacketSocket<P> {
15    pro: P,
16    fd: AsyncFd,
17}
18
19impl<P: Protocol> SeqPacketSocket<P> {
20    pub fn new(ctx: &IoContext, pro: P) -> io::Result<SeqPacketSocket<P>> {
21        let fd = try!(socket(&pro));
22        Ok(unsafe { Self::from_raw_fd(ctx, pro, fd) })
23    }
24
25    pub fn async_connect<F>(&self, ep: &P:: Endpoint, handler: F) -> F::Output
26        where F: Handler<(), io::Error>,
27    {
28        async_connect(self, ep, handler)
29    }
30
31    pub fn async_receive<F>(&self, buf: &mut [u8], flags: i32, handler: F) -> F::Output
32        where F: Handler<usize, io::Error>,
33    {
34        async_recv(self, buf, flags, handler)
35    }
36
37    pub fn async_send<F>(&self, buf: &[u8], flags: i32, handler: F) -> F::Output
38        where F: Handler<usize, io::Error>,
39    {
40        async_send(self, buf, flags, handler)
41    }
42
43    pub fn available(&self) -> io::Result<usize> {
44        let mut bytes = BytesReadable::default();
45        try!(self.io_control(&mut bytes));
46        Ok(bytes.get())
47    }
48
49    pub fn bind(&self, ep: &P::Endpoint) -> io::Result<()> {
50        bind(self, ep)
51    }
52
53    pub fn cancel(&self) -> &Self {
54        cancel(self);
55        self
56    }
57
58    pub fn connect(&self, ep: &P:: Endpoint) -> io::Result<()> {
59        connect(self, ep)
60    }
61
62    pub fn get_non_blocking(&self) -> io::Result<bool> {
63        getnonblock(self)
64    }
65
66    pub fn get_option<C>(&self) -> io::Result<C>
67        where C: GetSocketOption<P>,
68    {
69        getsockopt(self, &self.pro)
70    }
71
72    pub fn io_control<T>(&self, cmd: &mut T) -> io::Result<()>
73        where T: IoControl,
74    {
75        ioctl(self, cmd)
76    }
77
78    pub fn local_endpoint(&self) -> io::Result<P::Endpoint> {
79        getsockname(self, &self.pro)
80    }
81
82    pub fn receive(&self, buf: &mut [u8], flags: i32) -> io::Result<usize> {
83        recv(self, buf, flags)
84    }
85
86    pub fn remote_endpoint(&self) -> io::Result<P::Endpoint> {
87        getpeername(self, &self.pro)
88    }
89
90    pub fn send(&self, buf: &[u8], flags: i32) -> io::Result<usize> {
91        send(self, buf, flags)
92    }
93
94    pub fn set_non_blocking(&self, on: bool) -> io::Result<()> {
95        setnonblock(self, on)
96    }
97
98    pub fn set_option<C>(&self, cmd: C) -> io::Result<()>
99        where C: SetSocketOption<P>,
100    {
101        setsockopt(self, &self.pro, cmd)
102    }
103
104    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
105        shutdown(self, how)
106    }
107}
108
109impl<P: Protocol> fmt::Debug for SeqPacketSocket<P> {
110    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111        write!(f, "SeqPacketSocket({:?})", self.pro)
112    }
113}
114
115impl<P> AsRawFd for SeqPacketSocket<P> {
116    fn as_raw_fd(&self) -> RawFd {
117        self.fd.as_raw_fd()
118    }
119}
120
121unsafe impl<P> Send for SeqPacketSocket<P> {
122}
123
124unsafe impl<P> AsIoContext for SeqPacketSocket<P> {
125    fn as_ctx(&self) -> &IoContext {
126        self.fd.as_ctx()
127    }
128}
129
130impl<P: Protocol> Socket<P> for SeqPacketSocket<P> {
131    unsafe fn from_raw_fd(ctx: &IoContext, pro: P, fd: RawFd) -> SeqPacketSocket<P> {
132        SeqPacketSocket {
133            pro: pro,
134            fd: AsyncFd::new::<Self>(fd, ctx),
135        }
136    }
137
138    fn protocol(&self) -> P {
139        self.pro.clone()
140    }
141}
142
143impl<P: Protocol> AsAsyncFd for SeqPacketSocket<P> {
144    fn as_fd(&self) -> &AsyncFd {
145        &self.fd
146    }
147}