1#![allow(async_fn_in_trait)]
2#![warn(clippy::large_futures)]
3#![allow(clippy::uninlined_format_args)]
4#![allow(unknown_lints)]
5
6use core::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
7use core::ops::Deref;
8use core::pin::pin;
9
10use std::io;
11use std::net::{self, Shutdown, TcpStream, ToSocketAddrs, UdpSocket as StdUdpSocket};
12
13#[cfg(not(feature = "async-io-mini"))]
14use async_io::Async;
15#[cfg(feature = "async-io-mini")]
16use async_io_mini::Async;
17
18use futures_lite::io::{AsyncReadExt, AsyncWriteExt};
19
20use embedded_io_async::{ErrorType, Read, Write};
21
22use edge_nal::{
23 AddrType, Dns, MulticastV4, MulticastV6, Readable, TcpAccept, TcpBind, TcpConnect, TcpShutdown,
24 TcpSplit, UdpBind, UdpConnect, UdpReceive, UdpSend, UdpSplit, UdpSplitMulticast,
25};
26
27#[cfg(any(target_os = "linux", target_os = "android"))]
28pub use raw::*;
29
30#[derive(Default, Copy, Clone)]
37pub struct Stack(());
38
39impl Stack {
40 pub const fn new() -> Self {
42 Self(())
43 }
44}
45
46impl TcpConnect for Stack {
47 type Error = io::Error;
48
49 type Socket<'a>
50 = TcpSocket
51 where
52 Self: 'a;
53
54 async fn connect(&self, remote: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
55 let socket = Async::<TcpStream>::connect(remote).await?;
56
57 Ok(TcpSocket(socket))
58 }
59}
60
61impl TcpBind for Stack {
62 type Error = io::Error;
63
64 type Accept<'a>
65 = TcpAcceptor
66 where
67 Self: 'a;
68
69 async fn bind(&self, local: SocketAddr) -> Result<Self::Accept<'_>, Self::Error> {
70 let acceptor = Async::<net::TcpListener>::bind(local).map(TcpAcceptor)?;
71
72 Ok(acceptor)
73 }
74}
75
76pub struct TcpAcceptor(Async<net::TcpListener>);
78
79impl TcpAccept for TcpAcceptor {
80 type Error = io::Error;
81
82 type Socket<'a>
83 = TcpSocket
84 where
85 Self: 'a;
86
87 #[cfg(not(target_os = "espidf"))]
88 async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> {
89 let socket = self.0.accept().await.map(|(socket, _)| socket)?;
90
91 Ok((socket.as_ref().peer_addr()?, TcpSocket(socket)))
92 }
93
94 #[cfg(target_os = "espidf")]
95 async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> {
96 loop {
111 match self.0.as_ref().accept() {
112 Ok((socket, _)) => break Ok((socket.peer_addr()?, TcpSocket(Async::new(socket)?))),
113 Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
114 #[cfg(not(feature = "async-io-mini"))]
115 use async_io::Timer;
116 #[cfg(feature = "async-io-mini")]
117 use async_io_mini::Timer;
118
119 Timer::after(core::time::Duration::from_millis(20)).await;
120 }
121 Err(err) => break Err(err),
122 }
123 }
124 }
125}
126
127pub struct TcpSocket(Async<TcpStream>);
129
130impl TcpSocket {
131 pub const fn new(socket: Async<TcpStream>) -> Self {
136 Self(socket)
137 }
138
139 pub fn release(self) -> Async<TcpStream> {
141 self.0
142 }
143}
144
145impl Deref for TcpSocket {
146 type Target = Async<TcpStream>;
147
148 fn deref(&self) -> &Self::Target {
149 &self.0
150 }
151}
152
153impl ErrorType for TcpSocket {
154 type Error = io::Error;
155}
156
157impl Read for TcpSocket {
158 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
159 self.0.read(buf).await
160 }
161}
162
163impl Write for TcpSocket {
164 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
165 self.0.write(buf).await
166 }
167
168 async fn flush(&mut self) -> Result<(), Self::Error> {
169 self.0.flush().await
170 }
171}
172
173impl Readable for TcpSocket {
174 async fn readable(&mut self) -> Result<(), Self::Error> {
175 self.0.readable().await
176 }
177}
178
179impl ErrorType for &TcpSocket {
180 type Error = io::Error;
181}
182
183impl Read for &TcpSocket {
184 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
185 (&self.0).read(buf).await
186 }
187}
188
189impl Write for &TcpSocket {
190 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
191 (&self.0).write(buf).await
192 }
193
194 async fn flush(&mut self) -> Result<(), Self::Error> {
195 (&self.0).flush().await
196 }
197}
198
199impl Readable for &TcpSocket {
200 async fn readable(&mut self) -> Result<(), Self::Error> {
201 self.0.readable().await
202 }
203}
204
205impl TcpSplit for TcpSocket {
206 type Read<'a>
207 = &'a TcpSocket
208 where
209 Self: 'a;
210
211 type Write<'a>
212 = &'a TcpSocket
213 where
214 Self: 'a;
215
216 fn split(&mut self) -> (Self::Read<'_>, Self::Write<'_>) {
217 let socket = &*self;
218
219 (socket, socket)
220 }
221}
222
223impl TcpShutdown for TcpSocket {
224 async fn close(&mut self, what: edge_nal::Close) -> Result<(), Self::Error> {
225 match what {
226 edge_nal::Close::Read => self.0.as_ref().shutdown(Shutdown::Read)?,
227 edge_nal::Close::Write => self.0.as_ref().shutdown(Shutdown::Write)?,
228 edge_nal::Close::Both => self.0.as_ref().shutdown(Shutdown::Both)?,
229 }
230
231 Ok(())
232 }
233
234 async fn abort(&mut self) -> Result<(), Self::Error> {
235 Ok(())
238 }
239}
240
241impl UdpConnect for Stack {
242 type Error = io::Error;
243
244 type Socket<'a>
245 = UdpSocket
246 where
247 Self: 'a;
248
249 async fn connect(
250 &self,
251 local: SocketAddr,
252 remote: SocketAddr,
253 ) -> Result<Self::Socket<'_>, Self::Error> {
254 let socket = Async::<StdUdpSocket>::bind(local)?;
255
256 socket.as_ref().connect(remote)?;
257
258 Ok(UdpSocket(socket))
259 }
260}
261
262impl UdpBind for Stack {
263 type Error = io::Error;
264
265 type Socket<'a>
266 = UdpSocket
267 where
268 Self: 'a;
269
270 async fn bind(&self, local: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
271 let socket = Async::<StdUdpSocket>::bind(local)?;
272
273 socket.as_ref().set_broadcast(true)?;
274
275 Ok(UdpSocket(socket))
276 }
277}
278
279pub struct UdpSocket(Async<StdUdpSocket>);
281
282impl UdpSocket {
283 pub const fn new(socket: Async<StdUdpSocket>) -> Self {
288 Self(socket)
289 }
290
291 pub fn release(self) -> Async<StdUdpSocket> {
293 self.0
294 }
295
296 pub fn join_multicast_v4(
302 &self,
303 multiaddr: &Ipv4Addr,
304 interface: &Ipv4Addr,
305 ) -> Result<(), io::Error> {
306 #[cfg(not(target_os = "espidf"))]
307 self.as_ref().join_multicast_v4(multiaddr, interface)?;
308
309 #[cfg(target_os = "espidf")]
310 self.setsockopt_ipproto_ip(
311 multiaddr, interface, 3, )?;
313
314 Ok(())
315 }
316
317 pub fn leave_multicast_v4(
323 &self,
324 multiaddr: &Ipv4Addr,
325 interface: &Ipv4Addr,
326 ) -> Result<(), io::Error> {
327 #[cfg(not(target_os = "espidf"))]
328 self.as_ref().leave_multicast_v4(multiaddr, interface)?;
329
330 #[cfg(target_os = "espidf")]
331 self.setsockopt_ipproto_ip(
332 multiaddr, interface, 4, )?;
334
335 Ok(())
336 }
337
338 #[cfg(target_os = "espidf")]
339 pub fn setsockopt_ipproto_ip(
340 &self,
341 multiaddr: &Ipv4Addr,
342 interface: &Ipv4Addr,
343 option: u32,
344 ) -> Result<(), io::Error> {
345 let mreq = sys::ip_mreq {
352 imr_multiaddr: sys::in_addr {
353 s_addr: u32::from_ne_bytes(multiaddr.octets()),
354 },
355 imr_interface: sys::in_addr {
356 s_addr: u32::from_ne_bytes(interface.octets()),
357 },
358 };
359
360 use std::os::fd::AsRawFd;
361
362 syscall_los!(unsafe {
363 sys::setsockopt(
364 self.0.as_raw_fd(),
365 sys::IPPROTO_IP as _,
366 option as _,
367 &mreq as *const _ as *const _,
368 core::mem::size_of::<sys::ip_mreq>() as _,
369 )
370 })?;
371
372 Ok(())
373 }
374}
375
376impl Deref for UdpSocket {
377 type Target = Async<StdUdpSocket>;
378
379 fn deref(&self) -> &Self::Target {
380 &self.0
381 }
382}
383
384impl ErrorType for &UdpSocket {
385 type Error = io::Error;
386}
387
388impl UdpReceive for &UdpSocket {
389 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> {
390 let remote = self.0.as_ref().peer_addr();
391
392 let (len, remote) = if let Ok(remote) = remote {
393 let fut = pin!(self.0.recv(buffer));
395 let len = fut.await?;
396
397 (len, remote)
398 } else {
399 let fut = pin!(self.0.recv_from(buffer));
401 let (len, remote) = fut.await?;
402
403 (len, remote)
404 };
405
406 Ok((len, remote))
407 }
408}
409
410impl UdpSend for &UdpSocket {
411 async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
412 let is_remote = self.0.as_ref().peer_addr().is_ok();
413
414 if is_remote {
415 let mut offset = 0;
417
418 loop {
419 let fut = pin!(self.0.send(&data[offset..]));
420 offset += fut.await?;
421
422 if offset == data.len() {
423 break;
424 }
425 }
426 } else {
427 let mut offset = 0;
429
430 loop {
431 let fut = pin!(self.0.send_to(&data[offset..], remote));
432 offset += fut.await?;
433
434 if offset == data.len() {
435 break;
436 }
437 }
438 }
439
440 Ok(())
441 }
442}
443
444impl MulticastV4 for &UdpSocket {
445 async fn join_v4(
446 &mut self,
447 multicast_addr: Ipv4Addr,
448 interface: Ipv4Addr,
449 ) -> Result<(), Self::Error> {
450 self.join_multicast_v4(&multicast_addr, &interface)
451 }
452
453 async fn leave_v4(
454 &mut self,
455 multicast_addr: Ipv4Addr,
456 interface: Ipv4Addr,
457 ) -> Result<(), Self::Error> {
458 self.leave_multicast_v4(&multicast_addr, &interface)
459 }
460}
461
462impl MulticastV6 for &UdpSocket {
463 async fn join_v6(
464 &mut self,
465 multicast_addr: Ipv6Addr,
466 interface: u32,
467 ) -> Result<(), Self::Error> {
468 self.0
469 .as_ref()
470 .join_multicast_v6(&multicast_addr, interface)
471 }
472
473 async fn leave_v6(
474 &mut self,
475 multicast_addr: Ipv6Addr,
476 interface: u32,
477 ) -> Result<(), Self::Error> {
478 self.0
479 .as_ref()
480 .leave_multicast_v6(&multicast_addr, interface)
481 }
482}
483
484impl Readable for &UdpSocket {
485 async fn readable(&mut self) -> Result<(), Self::Error> {
486 self.0.readable().await
487 }
488}
489
490impl ErrorType for UdpSocket {
491 type Error = io::Error;
492}
493
494impl UdpReceive for UdpSocket {
495 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> {
496 let mut rself = &*self;
497
498 let fut = pin!(rself.receive(buffer));
499 fut.await
500 }
501}
502
503impl UdpSend for UdpSocket {
504 async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
505 let mut rself = &*self;
506
507 let fut = pin!(rself.send(remote, data));
508 fut.await
509 }
510}
511
512impl MulticastV4 for UdpSocket {
513 async fn join_v4(
514 &mut self,
515 multicast_addr: Ipv4Addr,
516 interface: Ipv4Addr,
517 ) -> Result<(), Self::Error> {
518 self.join_multicast_v4(&multicast_addr, &interface)
519 }
520
521 async fn leave_v4(
522 &mut self,
523 multicast_addr: Ipv4Addr,
524 interface: Ipv4Addr,
525 ) -> Result<(), Self::Error> {
526 self.leave_multicast_v4(&multicast_addr, &interface)
527 }
528}
529
530impl MulticastV6 for UdpSocket {
531 async fn join_v6(
532 &mut self,
533 multicast_addr: Ipv6Addr,
534 interface: u32,
535 ) -> Result<(), Self::Error> {
536 self.0
537 .as_ref()
538 .join_multicast_v6(&multicast_addr, interface)
539 }
540
541 async fn leave_v6(
542 &mut self,
543 multicast_addr: Ipv6Addr,
544 interface: u32,
545 ) -> Result<(), Self::Error> {
546 self.0
547 .as_ref()
548 .leave_multicast_v6(&multicast_addr, interface)
549 }
550}
551
552impl Readable for UdpSocket {
553 async fn readable(&mut self) -> Result<(), Self::Error> {
554 let mut rself = &*self;
555
556 let fut = pin!(rself.readable());
557 fut.await
558 }
559}
560
561impl UdpSplit for UdpSocket {
562 type Receive<'a>
563 = &'a Self
564 where
565 Self: 'a;
566
567 type Send<'a>
568 = &'a Self
569 where
570 Self: 'a;
571
572 fn split(&mut self) -> (Self::Receive<'_>, Self::Send<'_>) {
573 let socket = &*self;
574
575 (socket, socket)
576 }
577}
578
579impl UdpSplitMulticast for UdpSocket {
580 type MulticastV4<'a>
581 = &'a Self
582 where
583 Self: 'a;
584
585 type MulticastV6<'a>
586 = &'a Self
587 where
588 Self: 'a;
589
590 fn split_multicast(
591 &mut self,
592 ) -> (
593 Self::Receive<'_>,
594 Self::Send<'_>,
595 Self::MulticastV4<'_>,
596 Self::MulticastV6<'_>,
597 ) {
598 let socket = &*self;
599
600 (socket, socket, socket, socket)
601 }
602}
603
604impl Dns for Stack {
605 type Error = io::Error;
606
607 async fn get_host_by_name(
608 &self,
609 host: &str,
610 addr_type: AddrType,
611 ) -> Result<IpAddr, Self::Error> {
612 let host = host.to_string();
613
614 dns_lookup_host(&host, addr_type)
615 }
616
617 async fn get_host_by_address(
618 &self,
619 _addr: IpAddr,
620 _result: &mut [u8],
621 ) -> Result<usize, Self::Error> {
622 Err(io::ErrorKind::Unsupported.into())
623 }
624}
625
626fn dns_lookup_host(host: &str, addr_type: AddrType) -> Result<IpAddr, io::Error> {
628 (host, 0_u16)
629 .to_socket_addrs()?
630 .find(|addr| match addr_type {
631 AddrType::IPv4 => matches!(addr, std::net::SocketAddr::V4(_)),
632 AddrType::IPv6 => matches!(addr, std::net::SocketAddr::V6(_)),
633 AddrType::Either => true,
634 })
635 .map(|addr| match addr {
636 std::net::SocketAddr::V4(v4) => v4.ip().octets().into(),
637 std::net::SocketAddr::V6(v6) => v6.ip().octets().into(),
638 })
639 .ok_or_else(|| io::ErrorKind::AddrNotAvailable.into())
640}
641
642#[cfg(any(target_os = "linux", target_os = "android"))]
645mod raw {
646 use core::ops::Deref;
647 use core::pin::pin;
648
649 use std::io::{self, ErrorKind};
650 use std::os::fd::{AsFd, AsRawFd};
651
652 #[cfg(not(feature = "async-io-mini"))]
653 use async_io::Async;
654 #[cfg(feature = "async-io-mini")]
655 use async_io_mini::Async;
656
657 use edge_nal::{MacAddr, RawBind, RawReceive, RawSend, RawSplit, Readable};
658 use embedded_io_async::ErrorType;
659
660 use crate::sys;
661 use crate::syscall_los;
662
663 #[derive(Default, Copy, Clone)]
665 pub struct Interface(u32);
666
667 impl Interface {
668 pub const fn new(interface: u32) -> Self {
670 Self(interface)
671 }
672 }
673
674 impl RawBind for Interface {
675 type Error = io::Error;
676
677 type Socket<'a>
678 = RawSocket
679 where
680 Self: 'a;
681
682 async fn bind(&self) -> Result<Self::Socket<'_>, Self::Error> {
683 let socket = syscall_los!(unsafe {
684 sys::socket(
685 sys::PF_PACKET,
686 sys::SOCK_DGRAM,
687 (sys::ETH_P_IP as u16).to_be() as _,
688 )
689 })?;
690
691 let sockaddr = sys::sockaddr_ll {
692 sll_family: sys::AF_PACKET as _,
693 sll_protocol: (sys::ETH_P_IP as u16).to_be() as _,
694 sll_ifindex: self.0 as _,
695 sll_hatype: 0,
696 sll_pkttype: 0,
697 sll_halen: 0,
698 sll_addr: Default::default(),
699 };
700
701 syscall_los!(unsafe {
702 sys::bind(
703 socket,
704 &sockaddr as *const _ as *const _,
705 core::mem::size_of::<sys::sockaddr_ll>() as _,
706 )
707 })?;
708
709 let socket = {
715 use std::os::fd::FromRawFd;
716
717 unsafe { std::net::UdpSocket::from_raw_fd(socket) }
718 };
719
720 socket.set_broadcast(true)?;
721
722 Ok(RawSocket(Async::new(socket)?, self.0 as _))
723 }
724 }
725
726 pub struct RawSocket(Async<std::net::UdpSocket>, u32);
728
729 impl RawSocket {
730 pub const fn new(socket: Async<std::net::UdpSocket>, interface: u32) -> Self {
736 Self(socket, interface)
737 }
738
739 pub fn release(self) -> (Async<std::net::UdpSocket>, u32) {
741 (self.0, self.1)
742 }
743 }
744
745 impl Deref for RawSocket {
746 type Target = Async<std::net::UdpSocket>;
747
748 fn deref(&self) -> &Self::Target {
749 &self.0
750 }
751 }
752
753 impl ErrorType for &RawSocket {
754 type Error = io::Error;
755 }
756
757 impl RawReceive for &RawSocket {
758 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, MacAddr), Self::Error> {
759 let fut = pin!(self.0.read_with(|io| {
760 let mut storage: sys::sockaddr_storage = unsafe { core::mem::zeroed() };
761 let mut addrlen = core::mem::size_of_val(&storage) as sys::socklen_t;
762
763 let ret = syscall_los!(unsafe {
764 sys::recvfrom(
765 io.as_fd().as_raw_fd(),
766 buffer.as_mut_ptr() as *mut _,
767 buffer.len(),
768 0,
769 &mut storage as *mut _ as *mut _,
770 &mut addrlen,
771 )
772 })?;
773
774 let sockaddr = as_sockaddr_ll(&storage, addrlen as usize)?;
775
776 let mut mac = [0; 6];
777 mac.copy_from_slice(&sockaddr.sll_addr[..6]);
778
779 Ok((ret as usize, mac))
780 }));
781
782 fut.await
783 }
784 }
785
786 impl RawSend for &RawSocket {
787 async fn send(&mut self, mac: MacAddr, data: &[u8]) -> Result<(), Self::Error> {
788 let mut sockaddr = sys::sockaddr_ll {
789 sll_family: sys::AF_PACKET as _,
790 sll_protocol: (sys::ETH_P_IP as u16).to_be() as _,
791 sll_ifindex: self.1 as _,
792 sll_hatype: 0,
793 sll_pkttype: 0,
794 sll_halen: 0,
795 sll_addr: Default::default(),
796 };
797
798 sockaddr.sll_halen = mac.len() as _;
799 sockaddr.sll_addr[..mac.len()].copy_from_slice(&mac);
800
801 let fut = pin!(self.0.write_with(|io| {
802 let len = core::cmp::min(data.len(), u16::MAX as usize);
803
804 let ret = syscall_los!(unsafe {
805 sys::sendto(
806 io.as_fd().as_raw_fd(),
807 data.as_ptr() as *const _,
808 len,
809 sys::MSG_NOSIGNAL,
810 &sockaddr as *const _ as *const _,
811 core::mem::size_of::<sys::sockaddr_ll>() as _,
812 )
813 })?;
814 Ok(ret as usize)
815 }));
816
817 let len = fut.await?;
818
819 assert_eq!(len, data.len());
820
821 Ok(())
822 }
823 }
824
825 impl Readable for &RawSocket {
826 async fn readable(&mut self) -> Result<(), Self::Error> {
827 self.0.readable().await
828 }
829 }
830
831 impl ErrorType for RawSocket {
832 type Error = io::Error;
833 }
834
835 impl RawReceive for RawSocket {
836 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, MacAddr), Self::Error> {
837 let mut rself = &*self;
838
839 let fut = pin!(rself.receive(buffer));
840
841 fut.await
842 }
843 }
844
845 impl RawSend for RawSocket {
846 async fn send(&mut self, mac: MacAddr, data: &[u8]) -> Result<(), Self::Error> {
847 let mut rself = &*self;
848
849 let fut = pin!(rself.send(mac, data));
850
851 fut.await
852 }
853 }
854
855 impl RawSplit for RawSocket {
856 type Receive<'a>
857 = &'a Self
858 where
859 Self: 'a;
860
861 type Send<'a>
862 = &'a Self
863 where
864 Self: 'a;
865
866 fn split(&mut self) -> (Self::Receive<'_>, Self::Send<'_>) {
867 let socket = &*self;
868
869 (socket, socket)
870 }
871 }
872
873 impl Readable for RawSocket {
874 async fn readable(&mut self) -> Result<(), Self::Error> {
875 self.0.readable().await
876 }
877 }
878
879 fn as_sockaddr_ll(
880 storage: &sys::sockaddr_storage,
881 len: usize,
882 ) -> io::Result<&sys::sockaddr_ll> {
883 match storage.ss_family as core::ffi::c_int {
884 sys::AF_PACKET => {
885 assert!(len >= core::mem::size_of::<sys::sockaddr_ll>());
886 Ok(unsafe { (storage as *const _ as *const sys::sockaddr_ll).as_ref() }.unwrap())
887 }
888 _ => Err(io::Error::new(ErrorKind::InvalidInput, "invalid argument")),
889 }
890 }
891}
892
893#[cfg(any(target_os = "linux", target_os = "android", target_os = "espidf"))]
894mod sys {
895 pub use libc::*;
896
897 #[macro_export]
898 macro_rules! syscall {
899 ($ret:expr) => {{
900 let result = $ret;
901
902 if result != 0 {
903 Err(::std::io::Error::from_raw_os_error(result))
904 } else {
905 Ok(result)
906 }
907 }};
908 }
909
910 #[macro_export]
911 macro_rules! syscall_los {
912 ($ret:expr) => {{
913 let result = $ret;
914
915 if result == -1 {
916 Err(::std::io::Error::last_os_error())
917 } else {
918 Ok(result)
919 }
920 }};
921 }
922
923 #[macro_export]
924 macro_rules! syscall_los_eagain {
925 ($ret:expr) => {{
926 #[allow(unreachable_patterns)]
927 match syscall_los!($ret) {
928 Ok(_) => Ok(()),
929 Err(e)
930 if matches!(
931 e.raw_os_error(),
932 Some(sys::EINPROGRESS) | Some(sys::EAGAIN) | Some(sys::EWOULDBLOCK)
933 ) =>
934 {
935 Ok(())
936 }
937 Err(e) => Err(e),
938 }?;
939
940 Ok::<_, io::Error>(())
941 }};
942 }
943}