|
1 | 1 | use crate::convert::TryFrom;
|
2 | 2 | use crate::fmt;
|
3 |
| -use crate::io::{self, IoSlice, IoSliceMut}; |
| 3 | +use crate::io::{self, ErrorKind, IoSlice, IoSliceMut}; |
4 | 4 | use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
5 | 5 | use crate::str;
|
| 6 | +use crate::sys::hermit::abi; |
6 | 7 | use crate::sys::{unsupported, Void};
|
7 | 8 | use crate::time::Duration;
|
8 | 9 |
|
9 |
| -//// Iinitializes HermitCore's network stack |
10 |
| -pub unsafe fn init() -> io::Result<()> { |
| 10 | +/// Checks whether the HermitCore's socket interface has been started already, and |
| 11 | +/// if not, starts it. |
| 12 | +pub fn init() -> io::Result<()> { |
| 13 | + if abi::network_init() < 0 { |
| 14 | + return Err(io::Error::new(ErrorKind::Other, "Unable to initialize network interface")); |
| 15 | + } |
| 16 | + |
11 | 17 | Ok(())
|
12 | 18 | }
|
13 | 19 |
|
14 |
| -pub struct TcpStream(Void); |
| 20 | +pub struct TcpStream(abi::Handle); |
15 | 21 |
|
16 | 22 | impl TcpStream {
|
17 |
| - pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> { |
18 |
| - unsupported() |
| 23 | + pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> { |
| 24 | + let addr = addr?; |
| 25 | + |
| 26 | + match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) { |
| 27 | + Ok(handle) => Ok(TcpStream(handle)), |
| 28 | + _ => { |
| 29 | + Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket")) |
| 30 | + } |
| 31 | + } |
19 | 32 | }
|
20 | 33 |
|
21 |
| - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { |
22 |
| - unsupported() |
| 34 | + pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> { |
| 35 | + match abi::tcpstream::connect( |
| 36 | + saddr.ip().to_string().as_bytes(), |
| 37 | + saddr.port(), |
| 38 | + Some(duration.as_millis() as u64), |
| 39 | + ) { |
| 40 | + Ok(handle) => Ok(TcpStream(handle)), |
| 41 | + _ => { |
| 42 | + Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket")) |
| 43 | + } |
| 44 | + } |
23 | 45 | }
|
24 | 46 |
|
25 |
| - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { |
26 |
| - match self.0 {} |
| 47 | + pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> { |
| 48 | + abi::tcpstream::set_read_timeout(self.0, duration.map(|d| d.as_millis() as u64)) |
| 49 | + .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value")) |
27 | 50 | }
|
28 | 51 |
|
29 |
| - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { |
30 |
| - match self.0 {} |
| 52 | + pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> { |
| 53 | + abi::tcpstream::set_write_timeout(self.0, duration.map(|d| d.as_millis() as u64)) |
| 54 | + .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value")) |
31 | 55 | }
|
32 | 56 |
|
33 | 57 | pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
34 |
| - match self.0 {} |
| 58 | + let duration = abi::tcpstream::get_read_timeout(self.0) |
| 59 | + .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?; |
| 60 | + |
| 61 | + Ok(duration.map(|d| Duration::from_millis(d))) |
35 | 62 | }
|
36 | 63 |
|
37 | 64 | pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
38 |
| - match self.0 {} |
| 65 | + let duration = abi::tcpstream::get_write_timeout(self.0) |
| 66 | + .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?; |
| 67 | + |
| 68 | + Ok(duration.map(|d| Duration::from_millis(d))) |
39 | 69 | }
|
40 | 70 |
|
41 |
| - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { |
42 |
| - match self.0 {} |
| 71 | + pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { |
| 72 | + abi::tcpstream::peek(self.0, buf) |
| 73 | + .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed")) |
43 | 74 | }
|
44 | 75 |
|
45 |
| - pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { |
46 |
| - match self.0 {} |
| 76 | + pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> { |
| 77 | + self.read_vectored(&mut [IoSliceMut::new(buffer)]) |
47 | 78 | }
|
48 | 79 |
|
49 |
| - pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
50 |
| - match self.0 {} |
| 80 | + pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
| 81 | + let mut size: usize = 0; |
| 82 | + |
| 83 | + for i in ioslice.iter_mut() { |
| 84 | + let mut pos: usize = 0; |
| 85 | + |
| 86 | + while pos < i.len() { |
| 87 | + let ret = abi::tcpstream::read(self.0, &mut i[pos..]) |
| 88 | + .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to read on socket"))?; |
| 89 | + |
| 90 | + if ret == 0 { |
| 91 | + return Ok(size); |
| 92 | + } else { |
| 93 | + size += ret; |
| 94 | + pos += ret; |
| 95 | + } |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + Ok(size) |
51 | 100 | }
|
52 | 101 |
|
53 |
| - pub fn write(&self, _: &[u8]) -> io::Result<usize> { |
54 |
| - match self.0 {} |
| 102 | + pub fn write(&self, buffer: &[u8]) -> io::Result<usize> { |
| 103 | + self.write_vectored(&[IoSlice::new(buffer)]) |
55 | 104 | }
|
56 | 105 |
|
57 |
| - pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> { |
58 |
| - match self.0 {} |
| 106 | + pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> { |
| 107 | + let mut size: usize = 0; |
| 108 | + |
| 109 | + for i in ioslice.iter() { |
| 110 | + size += abi::tcpstream::write(self.0, i) |
| 111 | + .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to write on socket"))?; |
| 112 | + } |
| 113 | + |
| 114 | + Ok(size) |
59 | 115 | }
|
60 | 116 |
|
61 | 117 | pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
62 |
| - match self.0 {} |
| 118 | + Err(io::Error::new(ErrorKind::Other, "peer_addr isn't supported")) |
63 | 119 | }
|
64 | 120 |
|
65 | 121 | pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
66 |
| - match self.0 {} |
| 122 | + Err(io::Error::new(ErrorKind::Other, "socket_addr isn't supported")) |
67 | 123 | }
|
68 | 124 |
|
69 |
| - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { |
70 |
| - match self.0 {} |
| 125 | + pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { |
| 126 | + abi::tcpstream::shutdown(self.0, how as i32) |
| 127 | + .map_err(|_| io::Error::new(ErrorKind::Other, "unable to shutdown socket")) |
71 | 128 | }
|
72 | 129 |
|
73 | 130 | pub fn duplicate(&self) -> io::Result<TcpStream> {
|
74 |
| - match self.0 {} |
| 131 | + let handle = abi::tcpstream::duplicate(self.0) |
| 132 | + .map_err(|_| io::Error::new(ErrorKind::Other, "unable to duplicate stream"))?; |
| 133 | + |
| 134 | + Ok(TcpStream(handle)) |
75 | 135 | }
|
76 | 136 |
|
77 |
| - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { |
78 |
| - match self.0 {} |
| 137 | + pub fn set_nodelay(&self, mode: bool) -> io::Result<()> { |
| 138 | + abi::tcpstream::set_nodelay(self.0, mode) |
| 139 | + .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed")) |
79 | 140 | }
|
80 | 141 |
|
81 | 142 | pub fn nodelay(&self) -> io::Result<bool> {
|
82 |
| - match self.0 {} |
| 143 | + abi::tcpstream::nodelay(self.0) |
| 144 | + .map_err(|_| io::Error::new(ErrorKind::Other, "nodelay failed")) |
83 | 145 | }
|
84 | 146 |
|
85 |
| - pub fn set_ttl(&self, _: u32) -> io::Result<()> { |
86 |
| - match self.0 {} |
| 147 | + pub fn set_ttl(&self, tll: u32) -> io::Result<()> { |
| 148 | + abi::tcpstream::set_tll(self.0, tll) |
| 149 | + .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set TTL")) |
87 | 150 | }
|
88 | 151 |
|
89 | 152 | pub fn ttl(&self) -> io::Result<u32> {
|
90 |
| - match self.0 {} |
| 153 | + abi::tcpstream::get_tll(self.0) |
| 154 | + .map_err(|_| io::Error::new(ErrorKind::Other, "unable to get TTL")) |
91 | 155 | }
|
92 | 156 |
|
93 | 157 | pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
94 |
| - match self.0 {} |
| 158 | + Err(io::Error::new(ErrorKind::Other, "take_error isn't supported")) |
95 | 159 | }
|
96 | 160 |
|
97 |
| - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { |
98 |
| - match self.0 {} |
| 161 | + pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> { |
| 162 | + abi::tcpstream::set_nonblocking(self.0, mode) |
| 163 | + .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set blocking mode")) |
| 164 | + } |
| 165 | +} |
| 166 | + |
| 167 | +impl Drop for TcpStream { |
| 168 | + fn drop(&mut self) { |
| 169 | + let _ = abi::tcpstream::close(self.0); |
99 | 170 | }
|
100 | 171 | }
|
101 | 172 |
|
102 | 173 | impl fmt::Debug for TcpStream {
|
103 | 174 | fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
104 |
| - match self.0 {} |
| 175 | + Ok(()) |
105 | 176 | }
|
106 | 177 | }
|
107 | 178 |
|
108 |
| -pub struct TcpListener(Void); |
| 179 | +pub struct TcpListener(abi::Handle); |
109 | 180 |
|
110 | 181 | impl TcpListener {
|
111 | 182 | pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
|
112 |
| - unsupported() |
| 183 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
113 | 184 | }
|
114 | 185 |
|
115 | 186 | pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
116 |
| - match self.0 {} |
| 187 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
117 | 188 | }
|
118 | 189 |
|
119 | 190 | pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
|
120 |
| - match self.0 {} |
| 191 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
121 | 192 | }
|
122 | 193 |
|
123 | 194 | pub fn duplicate(&self) -> io::Result<TcpListener> {
|
124 |
| - match self.0 {} |
| 195 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
125 | 196 | }
|
126 | 197 |
|
127 | 198 | pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
128 |
| - match self.0 {} |
| 199 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
129 | 200 | }
|
130 | 201 |
|
131 | 202 | pub fn ttl(&self) -> io::Result<u32> {
|
132 |
| - match self.0 {} |
| 203 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
133 | 204 | }
|
134 | 205 |
|
135 | 206 | pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
|
136 |
| - match self.0 {} |
| 207 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
137 | 208 | }
|
138 | 209 |
|
139 | 210 | pub fn only_v6(&self) -> io::Result<bool> {
|
140 |
| - match self.0 {} |
| 211 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
141 | 212 | }
|
142 | 213 |
|
143 | 214 | pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
144 |
| - match self.0 {} |
| 215 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
145 | 216 | }
|
146 | 217 |
|
147 | 218 | pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
148 |
| - match self.0 {} |
| 219 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
149 | 220 | }
|
150 | 221 | }
|
151 | 222 |
|
152 | 223 | impl fmt::Debug for TcpListener {
|
153 | 224 | fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
154 |
| - match self.0 {} |
| 225 | + Ok(()) |
155 | 226 | }
|
156 | 227 | }
|
157 | 228 |
|
158 |
| -pub struct UdpSocket(Void); |
| 229 | +pub struct UdpSocket(abi::Handle); |
159 | 230 |
|
160 | 231 | impl UdpSocket {
|
161 | 232 | pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
|
162 |
| - unsupported() |
| 233 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
163 | 234 | }
|
164 | 235 |
|
165 | 236 | pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
166 |
| - match self.0 {} |
| 237 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
167 | 238 | }
|
168 | 239 |
|
169 | 240 | pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
170 |
| - match self.0 {} |
| 241 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
171 | 242 | }
|
172 | 243 |
|
173 | 244 | pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
174 |
| - match self.0 {} |
| 245 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
175 | 246 | }
|
176 | 247 |
|
177 | 248 | pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
178 |
| - match self.0 {} |
| 249 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
179 | 250 | }
|
180 | 251 |
|
181 | 252 | pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
|
182 |
| - match self.0 {} |
| 253 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
183 | 254 | }
|
184 | 255 |
|
185 | 256 | pub fn duplicate(&self) -> io::Result<UdpSocket> {
|
186 |
| - match self.0 {} |
| 257 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
187 | 258 | }
|
188 | 259 |
|
189 | 260 | pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
190 |
| - match self.0 {} |
| 261 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
191 | 262 | }
|
192 | 263 |
|
193 | 264 | pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
194 |
| - match self.0 {} |
| 265 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
195 | 266 | }
|
196 | 267 |
|
197 | 268 | pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
198 |
| - match self.0 {} |
| 269 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
199 | 270 | }
|
200 | 271 |
|
201 | 272 | pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
202 |
| - match self.0 {} |
| 273 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
203 | 274 | }
|
204 | 275 |
|
205 | 276 | pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
|
206 |
| - match self.0 {} |
| 277 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
207 | 278 | }
|
208 | 279 |
|
209 | 280 | pub fn broadcast(&self) -> io::Result<bool> {
|
210 |
| - match self.0 {} |
| 281 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
211 | 282 | }
|
212 | 283 |
|
213 | 284 | pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
|
214 |
| - match self.0 {} |
| 285 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
215 | 286 | }
|
216 | 287 |
|
217 | 288 | pub fn multicast_loop_v4(&self) -> io::Result<bool> {
|
218 |
| - match self.0 {} |
| 289 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
219 | 290 | }
|
220 | 291 |
|
221 | 292 | pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
|
222 |
| - match self.0 {} |
| 293 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
223 | 294 | }
|
224 | 295 |
|
225 | 296 | pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
|
226 |
| - match self.0 {} |
| 297 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
227 | 298 | }
|
228 | 299 |
|
229 | 300 | pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
|
230 |
| - match self.0 {} |
| 301 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
231 | 302 | }
|
232 | 303 |
|
233 | 304 | pub fn multicast_loop_v6(&self) -> io::Result<bool> {
|
234 |
| - match self.0 {} |
| 305 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
235 | 306 | }
|
236 | 307 |
|
237 | 308 | pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
238 |
| - match self.0 {} |
| 309 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
239 | 310 | }
|
240 | 311 |
|
241 | 312 | pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
242 |
| - match self.0 {} |
| 313 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
243 | 314 | }
|
244 | 315 |
|
245 | 316 | pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
|
246 |
| - match self.0 {} |
| 317 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
247 | 318 | }
|
248 | 319 |
|
249 | 320 | pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
|
250 |
| - match self.0 {} |
| 321 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
251 | 322 | }
|
252 | 323 |
|
253 | 324 | pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
254 |
| - match self.0 {} |
| 325 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
255 | 326 | }
|
256 | 327 |
|
257 | 328 | pub fn ttl(&self) -> io::Result<u32> {
|
258 |
| - match self.0 {} |
| 329 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
259 | 330 | }
|
260 | 331 |
|
261 | 332 | pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
262 |
| - match self.0 {} |
| 333 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
263 | 334 | }
|
264 | 335 |
|
265 | 336 | pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
266 |
| - match self.0 {} |
| 337 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
267 | 338 | }
|
268 | 339 |
|
269 | 340 | pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
|
270 |
| - match self.0 {} |
| 341 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
271 | 342 | }
|
272 | 343 |
|
273 | 344 | pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
|
274 |
| - match self.0 {} |
| 345 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
275 | 346 | }
|
276 | 347 |
|
277 | 348 | pub fn send(&self, _: &[u8]) -> io::Result<usize> {
|
278 |
| - match self.0 {} |
| 349 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
279 | 350 | }
|
280 | 351 |
|
281 | 352 | pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
|
282 |
| - match self.0 {} |
| 353 | + Err(io::Error::new(ErrorKind::Other, "not supported")) |
283 | 354 | }
|
284 | 355 | }
|
285 | 356 |
|
286 | 357 | impl fmt::Debug for UdpSocket {
|
287 | 358 | fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
288 |
| - match self.0 {} |
| 359 | + Ok(()) |
289 | 360 | }
|
290 | 361 | }
|
291 | 362 |
|
|
0 commit comments