]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/redox/net/tcp.rs
Auto merge of #57129 - RalfJung:check-bounds, r=oli-obk
[rust.git] / src / libstd / sys / redox / net / tcp.rs
1 use cmp;
2 use io::{self, Error, ErrorKind, Result};
3 use mem;
4 use net::{SocketAddr, Shutdown};
5 use path::Path;
6 use sys::fs::{File, OpenOptions};
7 use sys::syscall::TimeSpec;
8 use sys_common::{AsInner, FromInner, IntoInner};
9 use time::Duration;
10
11 use super::{path_to_peer_addr, path_to_local_addr};
12
13 #[derive(Debug)]
14 pub struct TcpStream(File);
15
16 impl TcpStream {
17     pub fn connect(addr: Result<&SocketAddr>) -> Result<TcpStream> {
18         let path = format!("tcp:{}", addr?);
19         let mut options = OpenOptions::new();
20         options.read(true);
21         options.write(true);
22         Ok(TcpStream(File::open(Path::new(path.as_str()), &options)?))
23     }
24
25     pub fn connect_timeout(_addr: &SocketAddr, _timeout: Duration) -> Result<TcpStream> {
26         Err(Error::new(ErrorKind::Other, "TcpStream::connect_timeout not implemented"))
27     }
28
29     pub fn duplicate(&self) -> Result<TcpStream> {
30         Ok(TcpStream(self.0.dup(&[])?))
31     }
32
33     pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
34         self.0.read(buf)
35     }
36
37     pub fn write(&self, buf: &[u8]) -> Result<usize> {
38         self.0.write(buf)
39     }
40
41     pub fn take_error(&self) -> Result<Option<Error>> {
42         Ok(None)
43     }
44
45     pub fn peer_addr(&self) -> Result<SocketAddr> {
46         let path = self.0.path()?;
47         Ok(path_to_peer_addr(path.to_str().unwrap_or("")))
48     }
49
50     pub fn socket_addr(&self) -> Result<SocketAddr> {
51         let path = self.0.path()?;
52         Ok(path_to_local_addr(path.to_str().unwrap_or("")))
53     }
54
55     pub fn peek(&self, _buf: &mut [u8]) -> Result<usize> {
56         Err(Error::new(ErrorKind::Other, "TcpStream::peek not implemented"))
57     }
58
59     pub fn shutdown(&self, _how: Shutdown) -> Result<()> {
60         Err(Error::new(ErrorKind::Other, "TcpStream::shutdown not implemented"))
61     }
62
63     pub fn nodelay(&self) -> Result<bool> {
64         Err(Error::new(ErrorKind::Other, "TcpStream::nodelay not implemented"))
65     }
66
67     pub fn nonblocking(&self) -> Result<bool> {
68         self.0.fd().nonblocking()
69     }
70
71     pub fn only_v6(&self) -> Result<bool> {
72         Err(Error::new(ErrorKind::Other, "TcpStream::only_v6 not implemented"))
73     }
74
75     pub fn ttl(&self) -> Result<u32> {
76         let mut ttl = [0];
77         let file = self.0.dup(b"ttl")?;
78         file.read(&mut ttl)?;
79         Ok(ttl[0] as u32)
80     }
81
82     pub fn read_timeout(&self) -> Result<Option<Duration>> {
83         let mut time = TimeSpec::default();
84         let file = self.0.dup(b"read_timeout")?;
85         if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
86             Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
87         } else {
88             Ok(None)
89         }
90     }
91
92     pub fn write_timeout(&self) -> Result<Option<Duration>> {
93         let mut time = TimeSpec::default();
94         let file = self.0.dup(b"write_timeout")?;
95         if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
96             Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
97         } else {
98             Ok(None)
99         }
100     }
101
102     pub fn set_nodelay(&self, _nodelay: bool) -> Result<()> {
103         Err(Error::new(ErrorKind::Other, "TcpStream::set_nodelay not implemented"))
104     }
105
106     pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> {
107         self.0.fd().set_nonblocking(nonblocking)
108     }
109
110     pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> {
111         Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented"))
112     }
113
114     pub fn set_ttl(&self, ttl: u32) -> Result<()> {
115         let file = self.0.dup(b"ttl")?;
116         file.write(&[cmp::min(ttl, 255) as u8])?;
117         Ok(())
118     }
119
120     pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
121         let file = self.0.dup(b"read_timeout")?;
122         if let Some(duration) = duration_option {
123             if duration.as_secs() == 0 && duration.subsec_nanos() == 0 {
124                 return Err(io::Error::new(io::ErrorKind::InvalidInput,
125                                           "cannot set a 0 duration timeout"));
126             }
127             file.write(&TimeSpec {
128                 tv_sec: duration.as_secs() as i64,
129                 tv_nsec: duration.subsec_nanos() as i32
130             })?;
131         } else {
132             file.write(&[])?;
133         }
134         Ok(())
135     }
136
137     pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
138         let file = self.0.dup(b"write_timeout")?;
139         if let Some(duration) = duration_option {
140             if duration.as_secs() == 0 && duration.subsec_nanos() == 0 {
141                 return Err(io::Error::new(io::ErrorKind::InvalidInput,
142                                           "cannot set a 0 duration timeout"));
143             }
144             file.write(&TimeSpec {
145                 tv_sec: duration.as_secs() as i64,
146                 tv_nsec: duration.subsec_nanos() as i32
147             })?;
148         } else {
149             file.write(&[])?;
150         }
151         Ok(())
152     }
153 }
154
155 impl AsInner<File> for TcpStream {
156     fn as_inner(&self) -> &File { &self.0 }
157 }
158
159 impl FromInner<File> for TcpStream {
160     fn from_inner(file: File) -> TcpStream {
161         TcpStream(file)
162     }
163 }
164
165 impl IntoInner<File> for TcpStream {
166     fn into_inner(self) -> File { self.0 }
167 }
168
169 #[derive(Debug)]
170 pub struct TcpListener(File);
171
172 impl TcpListener {
173     pub fn bind(addr: Result<&SocketAddr>) -> Result<TcpListener> {
174         let path = format!("tcp:/{}", addr?);
175         let mut options = OpenOptions::new();
176         options.read(true);
177         options.write(true);
178         Ok(TcpListener(File::open(Path::new(path.as_str()), &options)?))
179     }
180
181     pub fn accept(&self) -> Result<(TcpStream, SocketAddr)> {
182         let file = self.0.dup(b"listen")?;
183         let path = file.path()?;
184         let peer_addr = path_to_peer_addr(path.to_str().unwrap_or(""));
185         Ok((TcpStream(file), peer_addr))
186     }
187
188     pub fn duplicate(&self) -> Result<TcpListener> {
189         Ok(TcpListener(self.0.dup(&[])?))
190     }
191
192     pub fn take_error(&self) -> Result<Option<Error>> {
193         Ok(None)
194     }
195
196     pub fn socket_addr(&self) -> Result<SocketAddr> {
197         let path = self.0.path()?;
198         Ok(path_to_local_addr(path.to_str().unwrap_or("")))
199     }
200
201     pub fn nonblocking(&self) -> Result<bool> {
202         Err(Error::new(ErrorKind::Other, "TcpListener::nonblocking not implemented"))
203     }
204
205     pub fn only_v6(&self) -> Result<bool> {
206         Err(Error::new(ErrorKind::Other, "TcpListener::only_v6 not implemented"))
207     }
208
209     pub fn ttl(&self) -> Result<u32> {
210         let mut ttl = [0];
211         let file = self.0.dup(b"ttl")?;
212         file.read(&mut ttl)?;
213         Ok(ttl[0] as u32)
214     }
215
216     pub fn set_nonblocking(&self, _nonblocking: bool) -> Result<()> {
217         Err(Error::new(ErrorKind::Other, "TcpListener::set_nonblocking not implemented"))
218     }
219
220     pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> {
221         Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented"))
222     }
223
224     pub fn set_ttl(&self, ttl: u32) -> Result<()> {
225         let file = self.0.dup(b"ttl")?;
226         file.write(&[cmp::min(ttl, 255) as u8])?;
227         Ok(())
228     }
229 }
230
231 impl AsInner<File> for TcpListener {
232     fn as_inner(&self) -> &File { &self.0 }
233 }
234
235 impl FromInner<File> for TcpListener {
236     fn from_inner(file: File) -> TcpListener {
237         TcpListener(file)
238     }
239 }
240
241 impl IntoInner<File> for TcpListener {
242     fn into_inner(self) -> File { self.0 }
243 }