]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/hermit/net.rs
Rollup merge of #105362 - WaffleLapkin:🙅, r=oli-obk
[rust.git] / library / std / src / sys / hermit / net.rs
1 use crate::fmt;
2 use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
3 use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
4 use crate::str;
5 use crate::sync::Arc;
6 use crate::sys::hermit::abi;
7 use crate::sys::hermit::abi::IpAddress::{Ipv4, Ipv6};
8 use crate::sys::unsupported;
9 use crate::sys_common::AsInner;
10 use crate::time::Duration;
11
12 /// Checks whether the HermitCore's socket interface has been started already, and
13 /// if not, starts it.
14 pub fn init() -> io::Result<()> {
15     if abi::network_init() < 0 {
16         return Err(io::const_io_error!(
17             ErrorKind::Uncategorized,
18             "Unable to initialize network interface",
19         ));
20     }
21
22     Ok(())
23 }
24
25 #[derive(Debug, Clone)]
26 pub struct Socket(abi::Handle);
27
28 impl AsInner<abi::Handle> for Socket {
29     fn as_inner(&self) -> &abi::Handle {
30         &self.0
31     }
32 }
33
34 impl Drop for Socket {
35     fn drop(&mut self) {
36         let _ = abi::tcpstream::close(self.0);
37     }
38 }
39
40 // Arc is used to count the number of used sockets.
41 // Only if all sockets are released, the drop
42 // method will close the socket.
43 #[derive(Clone)]
44 pub struct TcpStream(Arc<Socket>);
45
46 impl TcpStream {
47     pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
48         let addr = addr?;
49
50         match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
51             Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
52             _ => Err(io::const_io_error!(
53                 ErrorKind::Uncategorized,
54                 "Unable to initiate a connection on a socket",
55             )),
56         }
57     }
58
59     pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
60         match abi::tcpstream::connect(
61             saddr.ip().to_string().as_bytes(),
62             saddr.port(),
63             Some(duration.as_millis() as u64),
64         ) {
65             Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
66             _ => Err(io::const_io_error!(
67                 ErrorKind::Uncategorized,
68                 "Unable to initiate a connection on a socket",
69             )),
70         }
71     }
72
73     pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
74         abi::tcpstream::set_read_timeout(*self.0.as_inner(), duration.map(|d| d.as_millis() as u64))
75             .map_err(|_| {
76                 io::const_io_error!(ErrorKind::Uncategorized, "Unable to set timeout value")
77             })
78     }
79
80     pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
81         abi::tcpstream::set_write_timeout(
82             *self.0.as_inner(),
83             duration.map(|d| d.as_millis() as u64),
84         )
85         .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "Unable to set timeout value"))
86     }
87
88     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
89         let duration = abi::tcpstream::get_read_timeout(*self.0.as_inner()).map_err(|_| {
90             io::const_io_error!(ErrorKind::Uncategorized, "Unable to determine timeout value")
91         })?;
92
93         Ok(duration.map(|d| Duration::from_millis(d)))
94     }
95
96     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
97         let duration = abi::tcpstream::get_write_timeout(*self.0.as_inner()).map_err(|_| {
98             io::const_io_error!(ErrorKind::Uncategorized, "Unable to determine timeout value")
99         })?;
100
101         Ok(duration.map(|d| Duration::from_millis(d)))
102     }
103
104     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
105         abi::tcpstream::peek(*self.0.as_inner(), buf)
106             .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "peek failed"))
107     }
108
109     pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
110         self.read_vectored(&mut [IoSliceMut::new(buffer)])
111     }
112
113     pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
114         let mut size: usize = 0;
115
116         for i in ioslice.iter_mut() {
117             let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..]).map_err(|_| {
118                 io::const_io_error!(ErrorKind::Uncategorized, "Unable to read on socket")
119             })?;
120
121             if ret != 0 {
122                 size += ret;
123             }
124         }
125
126         Ok(size)
127     }
128
129     #[inline]
130     pub fn is_read_vectored(&self) -> bool {
131         true
132     }
133
134     pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
135         self.write_vectored(&[IoSlice::new(buffer)])
136     }
137
138     pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> {
139         let mut size: usize = 0;
140
141         for i in ioslice.iter() {
142             size += abi::tcpstream::write(*self.0.as_inner(), i).map_err(|_| {
143                 io::const_io_error!(ErrorKind::Uncategorized, "Unable to write on socket")
144             })?;
145         }
146
147         Ok(size)
148     }
149
150     #[inline]
151     pub fn is_write_vectored(&self) -> bool {
152         true
153     }
154
155     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
156         let (ipaddr, port) = abi::tcpstream::peer_addr(*self.0.as_inner())
157             .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "peer_addr failed"))?;
158
159         let saddr = match ipaddr {
160             Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
161             Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
162             _ => {
163                 return Err(io::const_io_error!(ErrorKind::Uncategorized, "peer_addr failed"));
164             }
165         };
166
167         Ok(saddr)
168     }
169
170     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
171         unsupported()
172     }
173
174     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
175         abi::tcpstream::shutdown(*self.0.as_inner(), how as i32)
176             .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to shutdown socket"))
177     }
178
179     pub fn duplicate(&self) -> io::Result<TcpStream> {
180         Ok(self.clone())
181     }
182
183     pub fn set_linger(&self, _linger: Option<Duration>) -> io::Result<()> {
184         unsupported()
185     }
186
187     pub fn linger(&self) -> io::Result<Option<Duration>> {
188         unsupported()
189     }
190
191     pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
192         abi::tcpstream::set_nodelay(*self.0.as_inner(), mode)
193             .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "set_nodelay failed"))
194     }
195
196     pub fn nodelay(&self) -> io::Result<bool> {
197         abi::tcpstream::nodelay(*self.0.as_inner())
198             .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "nodelay failed"))
199     }
200
201     pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
202         abi::tcpstream::set_tll(*self.0.as_inner(), tll)
203             .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to set TTL"))
204     }
205
206     pub fn ttl(&self) -> io::Result<u32> {
207         abi::tcpstream::get_tll(*self.0.as_inner())
208             .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to get TTL"))
209     }
210
211     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
212         unsupported()
213     }
214
215     pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
216         abi::tcpstream::set_nonblocking(*self.0.as_inner(), mode).map_err(|_| {
217             io::const_io_error!(ErrorKind::Uncategorized, "unable to set blocking mode")
218         })
219     }
220 }
221
222 impl fmt::Debug for TcpStream {
223     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
224         Ok(())
225     }
226 }
227
228 #[derive(Clone)]
229 pub struct TcpListener(SocketAddr);
230
231 impl TcpListener {
232     pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
233         let addr = addr?;
234
235         Ok(TcpListener(*addr))
236     }
237
238     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
239         Ok(self.0)
240     }
241
242     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
243         let (handle, ipaddr, port) = abi::tcplistener::accept(self.0.port())
244             .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "accept failed"))?;
245         let saddr = match ipaddr {
246             Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
247             Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
248             _ => {
249                 return Err(io::const_io_error!(ErrorKind::Uncategorized, "accept failed"));
250             }
251         };
252
253         Ok((TcpStream(Arc::new(Socket(handle))), saddr))
254     }
255
256     pub fn duplicate(&self) -> io::Result<TcpListener> {
257         Ok(self.clone())
258     }
259
260     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
261         unsupported()
262     }
263
264     pub fn ttl(&self) -> io::Result<u32> {
265         unsupported()
266     }
267
268     pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
269         unsupported()
270     }
271
272     pub fn only_v6(&self) -> io::Result<bool> {
273         unsupported()
274     }
275
276     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
277         unsupported()
278     }
279
280     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
281         unsupported()
282     }
283 }
284
285 impl fmt::Debug for TcpListener {
286     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
287         Ok(())
288     }
289 }
290
291 pub struct UdpSocket(abi::Handle);
292
293 impl UdpSocket {
294     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
295         unsupported()
296     }
297
298     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
299         unsupported()
300     }
301
302     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
303         unsupported()
304     }
305
306     pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
307         unsupported()
308     }
309
310     pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
311         unsupported()
312     }
313
314     pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
315         unsupported()
316     }
317
318     pub fn duplicate(&self) -> io::Result<UdpSocket> {
319         unsupported()
320     }
321
322     pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
323         unsupported()
324     }
325
326     pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
327         unsupported()
328     }
329
330     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
331         unsupported()
332     }
333
334     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
335         unsupported()
336     }
337
338     pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
339         unsupported()
340     }
341
342     pub fn broadcast(&self) -> io::Result<bool> {
343         unsupported()
344     }
345
346     pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
347         unsupported()
348     }
349
350     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
351         unsupported()
352     }
353
354     pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
355         unsupported()
356     }
357
358     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
359         unsupported()
360     }
361
362     pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
363         unsupported()
364     }
365
366     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
367         unsupported()
368     }
369
370     pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
371         unsupported()
372     }
373
374     pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
375         unsupported()
376     }
377
378     pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
379         unsupported()
380     }
381
382     pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
383         unsupported()
384     }
385
386     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
387         unsupported()
388     }
389
390     pub fn ttl(&self) -> io::Result<u32> {
391         unsupported()
392     }
393
394     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
395         unsupported()
396     }
397
398     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
399         unsupported()
400     }
401
402     pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
403         unsupported()
404     }
405
406     pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
407         unsupported()
408     }
409
410     pub fn send(&self, _: &[u8]) -> io::Result<usize> {
411         unsupported()
412     }
413
414     pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
415         unsupported()
416     }
417 }
418
419 impl fmt::Debug for UdpSocket {
420     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
421         Ok(())
422     }
423 }
424
425 pub struct LookupHost(!);
426
427 impl LookupHost {
428     pub fn port(&self) -> u16 {
429         self.0
430     }
431 }
432
433 impl Iterator for LookupHost {
434     type Item = SocketAddr;
435     fn next(&mut self) -> Option<SocketAddr> {
436         self.0
437     }
438 }
439
440 impl TryFrom<&str> for LookupHost {
441     type Error = io::Error;
442
443     fn try_from(_v: &str) -> io::Result<LookupHost> {
444         unsupported()
445     }
446 }
447
448 impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
449     type Error = io::Error;
450
451     fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
452         unsupported()
453     }
454 }
455
456 #[allow(nonstandard_style)]
457 pub mod netc {
458     pub const AF_INET: u8 = 0;
459     pub const AF_INET6: u8 = 1;
460     pub type sa_family_t = u8;
461
462     #[derive(Copy, Clone)]
463     pub struct in_addr {
464         pub s_addr: u32,
465     }
466
467     #[derive(Copy, Clone)]
468     pub struct sockaddr_in {
469         pub sin_family: sa_family_t,
470         pub sin_port: u16,
471         pub sin_addr: in_addr,
472     }
473
474     #[derive(Copy, Clone)]
475     pub struct in6_addr {
476         pub s6_addr: [u8; 16],
477     }
478
479     #[derive(Copy, Clone)]
480     pub struct sockaddr_in6 {
481         pub sin6_family: sa_family_t,
482         pub sin6_port: u16,
483         pub sin6_addr: in6_addr,
484         pub sin6_flowinfo: u32,
485         pub sin6_scope_id: u32,
486     }
487
488     #[derive(Copy, Clone)]
489     pub struct sockaddr {}
490 }