diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2025-02-05 19:09:35 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-05 19:09:35 +0800 |
| commit | ff339fbbf4c535afdff3ceaa968f0fe36be23b59 (patch) | |
| tree | 741ba861f64fd404bc996559a9af467a8ff3dd51 /library/std/src/sys/pal | |
| parent | cc58e8b7ec3c09a04b4d2420ee9a328bfad73e15 (diff) | |
| parent | 8a3cb1351183e963da96ae6bbb8dcce478be9f7b (diff) | |
| download | rust-ff339fbbf4c535afdff3ceaa968f0fe36be23b59.tar.gz rust-ff339fbbf4c535afdff3ceaa968f0fe36be23b59.zip | |
Rollup merge of #136449 - joboet:move_pal_net, r=ChrisDenton
std: move network code into `sys` As per #117276, this PR moves `sys_common::net` and the `sys::pal::net` into the newly created `sys::net` module. In order to support #135141, I've moved all the current network code into a separate `connection` module, future functions like `hostname` can live in separate modules. I'll probably do a follow-up PR and clean up some of the actual code, this is mostly just a reorganization.
Diffstat (limited to 'library/std/src/sys/pal')
29 files changed, 5 insertions, 6158 deletions
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index d833c9d632c..032007aa4dc 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -24,7 +24,6 @@ pub mod fd; pub mod fs; pub mod futex; pub mod io; -pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys/pal/hermit/net.rs b/library/std/src/sys/pal/hermit/net.rs deleted file mode 100644 index 4e12374203e..00000000000 --- a/library/std/src/sys/pal/hermit/net.rs +++ /dev/null @@ -1,347 +0,0 @@ -#![allow(dead_code)] - -use core::ffi::c_int; - -use super::fd::FileDesc; -use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Shutdown, SocketAddr}; -use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd}; -use crate::sys::time::Instant; -use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::Duration; -use crate::{cmp, mem}; - -#[allow(unused_extern_crates)] -pub extern crate hermit_abi as netc; - -pub use crate::sys::{cvt, cvt_r}; - -pub type wrlen_t = usize; - -pub fn cvt_gai(err: i32) -> io::Result<()> { - if err == 0 { - return Ok(()); - } - - let detail = ""; - - Err(io::Error::new( - io::ErrorKind::Uncategorized, - &format!("failed to lookup address information: {detail}")[..], - )) -} - -pub fn init() {} - -#[derive(Debug)] -pub struct Socket(FileDesc); - -impl Socket { - pub fn new(addr: &SocketAddr, ty: i32) -> io::Result<Socket> { - let fam = match *addr { - SocketAddr::V4(..) => netc::AF_INET, - SocketAddr::V6(..) => netc::AF_INET6, - }; - Socket::new_raw(fam, ty) - } - - pub fn new_raw(fam: i32, ty: i32) -> io::Result<Socket> { - let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?; - Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) - } - - pub fn new_pair(_fam: i32, _ty: i32) -> io::Result<(Socket, Socket)> { - unimplemented!() - } - - pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { - let (addr, len) = addr.into_inner(); - cvt_r(|| unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?; - Ok(()) - } - - pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { - self.set_nonblocking(true)?; - let r = unsafe { - let (addr, len) = addr.into_inner(); - cvt(netc::connect(self.as_raw_fd(), addr.as_ptr(), len)) - }; - self.set_nonblocking(false)?; - - match r { - Ok(_) => return Ok(()), - // there's no ErrorKind for EINPROGRESS :( - Err(ref e) if e.raw_os_error() == Some(netc::errno::EINPROGRESS) => {} - Err(e) => return Err(e), - } - - let mut pollfd = netc::pollfd { fd: self.as_raw_fd(), events: netc::POLLOUT, revents: 0 }; - - if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let start = Instant::now(); - - loop { - let elapsed = start.elapsed(); - if elapsed >= timeout { - return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); - } - - let timeout = timeout - elapsed; - let mut timeout = timeout - .as_secs() - .saturating_mul(1_000) - .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000); - if timeout == 0 { - timeout = 1; - } - - let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; - - match unsafe { netc::poll(&mut pollfd, 1, timeout) } { - -1 => { - let err = io::Error::last_os_error(); - if !err.is_interrupted() { - return Err(err); - } - } - 0 => {} - _ => { - // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look - // for POLLHUP rather than read readiness - if pollfd.revents & netc::POLLHUP != 0 { - let e = self.take_error()?.unwrap_or_else(|| { - io::const_error!( - io::ErrorKind::Uncategorized, - "no error set after POLLHUP", - ) - }); - return Err(e); - } - - return Ok(()); - } - } - } - } - - pub fn accept( - &self, - storage: *mut netc::sockaddr, - len: *mut netc::socklen_t, - ) -> io::Result<Socket> { - let fd = cvt(unsafe { netc::accept(self.0.as_raw_fd(), storage, len) })?; - Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) - } - - pub fn duplicate(&self) -> io::Result<Socket> { - let fd = cvt(unsafe { netc::dup(self.0.as_raw_fd()) })?; - Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) - } - - fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: i32) -> io::Result<()> { - let ret = cvt(unsafe { - netc::recv( - self.0.as_raw_fd(), - buf.as_mut().as_mut_ptr() as *mut u8, - buf.capacity(), - flags, - ) - })?; - unsafe { - buf.advance_unchecked(ret as usize); - } - Ok(()) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), 0)?; - Ok(buf.len()) - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), netc::MSG_PEEK)?; - Ok(buf.len()) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.recv_with_flags(buf, 0) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - self.0.read_vectored(bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - self.0.is_read_vectored() - } - - fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> { - let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; - - let n = cvt(unsafe { - netc::recvfrom( - self.as_raw_fd(), - buf.as_mut_ptr(), - buf.len(), - flags, - (&raw mut storage) as *mut _, - &mut addrlen, - ) - })?; - Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?)) - } - - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, 0) - } - - pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, netc::MSG_PEEK) - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - self.0.write_vectored(bufs) - } - - pub fn is_write_vectored(&self) -> bool { - self.0.is_write_vectored() - } - - pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> { - let timeout = match dur { - Some(dur) => { - if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let secs = if dur.as_secs() > netc::time_t::MAX as u64 { - netc::time_t::MAX - } else { - dur.as_secs() as netc::time_t - }; - let mut timeout = netc::timeval { - tv_sec: secs, - tv_usec: dur.subsec_micros() as netc::suseconds_t, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => netc::timeval { tv_sec: 0, tv_usec: 0 }, - }; - - setsockopt(self, netc::SOL_SOCKET, kind, timeout) - } - - pub fn timeout(&self, kind: i32) -> io::Result<Option<Duration>> { - let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?; - if raw.tv_sec == 0 && raw.tv_usec == 0 { - Ok(None) - } else { - let sec = raw.tv_sec as u64; - let nsec = (raw.tv_usec as u32) * 1000; - Ok(Some(Duration::new(sec, nsec))) - } - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - let how = match how { - Shutdown::Write => netc::SHUT_WR, - Shutdown::Read => netc::SHUT_RD, - Shutdown::Both => netc::SHUT_RDWR, - }; - cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?; - Ok(()) - } - - pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { - let linger = netc::linger { - l_onoff: linger.is_some() as i32, - l_linger: linger.unwrap_or_default().as_secs() as libc::c_int, - }; - - setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - let val: netc::linger = getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)?; - - Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) - } - - pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { - let value: i32 = if nodelay { 1 } else { 0 }; - setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, value) - } - - pub fn nodelay(&self) -> io::Result<bool> { - let raw: i32 = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?; - Ok(raw != 0) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut nonblocking: i32 = if nonblocking { 1 } else { 0 }; - cvt(unsafe { - netc::ioctl( - self.as_raw_fd(), - netc::FIONBIO, - (&raw mut nonblocking) as *mut core::ffi::c_void, - ) - }) - .map(drop) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimplemented!() - } - - // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl AsInner<FileDesc> for Socket { - #[inline] - fn as_inner(&self) -> &FileDesc { - &self.0 - } -} - -impl IntoInner<FileDesc> for Socket { - fn into_inner(self) -> FileDesc { - self.0 - } -} - -impl FromInner<FileDesc> for Socket { - fn from_inner(file_desc: FileDesc) -> Self { - Self(file_desc) - } -} - -impl AsFd for Socket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index ce8a2fed4bc..0f5935d0c71 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -17,7 +17,6 @@ pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; mod libunwind_integration; -pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys/pal/sgx/net.rs b/library/std/src/sys/pal/sgx/net.rs deleted file mode 100644 index c966886d163..00000000000 --- a/library/std/src/sys/pal/sgx/net.rs +++ /dev/null @@ -1,536 +0,0 @@ -use super::abi::usercalls; -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs}; -use crate::sync::Arc; -use crate::sys::fd::FileDesc; -use crate::sys::{AsInner, FromInner, IntoInner, TryIntoInner, sgx_ineffective, unsupported}; -use crate::time::Duration; -use crate::{error, fmt}; - -const DEFAULT_FAKE_TTL: u32 = 64; - -#[derive(Debug, Clone)] -pub struct Socket { - inner: Arc<FileDesc>, - local_addr: Option<String>, -} - -impl Socket { - fn new(fd: usercalls::raw::Fd, local_addr: String) -> Socket { - Socket { inner: Arc::new(FileDesc::new(fd)), local_addr: Some(local_addr) } - } -} - -impl AsInner<FileDesc> for Socket { - #[inline] - fn as_inner(&self) -> &FileDesc { - &self.inner - } -} - -impl TryIntoInner<FileDesc> for Socket { - fn try_into_inner(self) -> Result<FileDesc, Socket> { - let Socket { inner, local_addr } = self; - Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr }) - } -} - -impl FromInner<(FileDesc, Option<String>)> for Socket { - fn from_inner((inner, local_addr): (FileDesc, Option<String>)) -> Socket { - Socket { inner: Arc::new(inner), local_addr } - } -} - -#[derive(Clone)] -pub struct TcpStream { - inner: Socket, - peer_addr: Option<String>, -} - -impl fmt::Debug for TcpStream { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut res = f.debug_struct("TcpStream"); - - if let Some(ref addr) = self.inner.local_addr { - res.field("addr", addr); - } - - if let Some(ref peer) = self.peer_addr { - res.field("peer", peer); - } - - res.field("fd", &self.inner.inner.as_inner()).finish() - } -} - -fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> { - match result { - Ok(saddr) => Ok(saddr.to_string()), - // need to downcast twice because io::Error::into_inner doesn't return the original - // value if the conversion fails - Err(e) => { - if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() { - Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host) - } else { - Err(e) - } - } - } -} - -fn addr_to_sockaddr(addr: Option<&str>) -> io::Result<SocketAddr> { - addr.ok_or(io::ErrorKind::AddrNotAvailable)? - .to_socket_addrs() - // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry - .map(|mut it| it.next().unwrap()) -} - -impl TcpStream { - pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - let addr = io_err_to_addr(addr)?; - let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?; - Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) }) - } - - pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> { - if dur == Duration::default() { - return Err(io::Error::ZERO_TIMEOUT); - } - Self::connect(Ok(addr)) // FIXME: ignoring timeout - } - - pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> { - match dur { - Some(dur) if dur == Duration::default() => { - return Err(io::Error::ZERO_TIMEOUT); - } - _ => sgx_ineffective(()), - } - } - - pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> { - match dur { - Some(dur) if dur == Duration::default() => { - return Err(io::Error::ZERO_TIMEOUT); - } - _ => sgx_ineffective(()), - } - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - sgx_ineffective(None) - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - sgx_ineffective(None) - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - Ok(0) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - self.inner.inner.read(buf) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.inner.inner.read_buf(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - self.inner.inner.read_vectored(bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - self.inner.inner.is_read_vectored() - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - self.inner.inner.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - self.inner.inner.write_vectored(bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - self.inner.inner.is_write_vectored() - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - addr_to_sockaddr(self.peer_addr.as_deref()) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - addr_to_sockaddr(self.inner.local_addr.as_deref()) - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - sgx_ineffective(()) - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - Ok(self.clone()) - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - sgx_ineffective(()) - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - sgx_ineffective(None) - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - sgx_ineffective(()) - } - - pub fn nodelay(&self) -> io::Result<bool> { - sgx_ineffective(false) - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - sgx_ineffective(()) - } - - pub fn ttl(&self) -> io::Result<u32> { - sgx_ineffective(DEFAULT_FAKE_TTL) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - Ok(None) - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - sgx_ineffective(()) - } -} - -impl AsInner<Socket> for TcpStream { - #[inline] - fn as_inner(&self) -> &Socket { - &self.inner - } -} - -// `Inner` includes `peer_addr` so that a `TcpStream` maybe correctly -// reconstructed if `Socket::try_into_inner` fails. -impl IntoInner<(Socket, Option<String>)> for TcpStream { - fn into_inner(self) -> (Socket, Option<String>) { - (self.inner, self.peer_addr) - } -} - -impl FromInner<(Socket, Option<String>)> for TcpStream { - fn from_inner((inner, peer_addr): (Socket, Option<String>)) -> TcpStream { - TcpStream { inner, peer_addr } - } -} - -#[derive(Clone)] -pub struct TcpListener { - inner: Socket, -} - -impl fmt::Debug for TcpListener { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut res = f.debug_struct("TcpListener"); - - if let Some(ref addr) = self.inner.local_addr { - res.field("addr", addr); - } - - res.field("fd", &self.inner.inner.as_inner()).finish() - } -} - -impl TcpListener { - pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - let addr = io_err_to_addr(addr)?; - let (fd, local_addr) = usercalls::bind_stream(&addr)?; - Ok(TcpListener { inner: Socket::new(fd, local_addr) }) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - addr_to_sockaddr(self.inner.local_addr.as_deref()) - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?; - let peer_addr = Some(peer_addr); - let ret_peer = - addr_to_sockaddr(peer_addr.as_deref()).unwrap_or_else(|_| ([0; 4], 0).into()); - Ok((TcpStream { inner: Socket::new(fd, local_addr), peer_addr }, ret_peer)) - } - - pub fn duplicate(&self) -> io::Result<TcpListener> { - Ok(self.clone()) - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - sgx_ineffective(()) - } - - pub fn ttl(&self) -> io::Result<u32> { - sgx_ineffective(DEFAULT_FAKE_TTL) - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - sgx_ineffective(()) - } - - pub fn only_v6(&self) -> io::Result<bool> { - sgx_ineffective(false) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - Ok(None) - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - sgx_ineffective(()) - } -} - -impl AsInner<Socket> for TcpListener { - #[inline] - fn as_inner(&self) -> &Socket { - &self.inner - } -} - -impl IntoInner<Socket> for TcpListener { - fn into_inner(self) -> Socket { - self.inner - } -} - -impl FromInner<Socket> for TcpListener { - fn from_inner(inner: Socket) -> TcpListener { - TcpListener { inner } - } -} - -pub struct UdpSocket(!); - -impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - unsupported() - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.0 - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.0 - } - - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { - self.0 - } - - pub fn duplicate(&self) -> io::Result<UdpSocket> { - self.0 - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn broadcast(&self) -> io::Result<bool> { - self.0 - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - self.0 - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - self.0 - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - self.0 - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - self.0 - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - self.0 - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - self.0 - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - self.0 - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn ttl(&self) -> io::Result<u32> { - self.0 - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - self.0 - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn send(&self, _: &[u8]) -> io::Result<usize> { - self.0 - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - self.0 - } -} - -impl fmt::Debug for UdpSocket { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 - } -} - -#[derive(Debug)] -pub struct NonIpSockAddr { - host: String, -} - -impl error::Error for NonIpSockAddr { - #[allow(deprecated)] - fn description(&self) -> &str { - "Failed to convert address to SocketAddr" - } -} - -impl fmt::Display for NonIpSockAddr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Failed to convert address to SocketAddr: {}", self.host) - } -} - -pub struct LookupHost(!); - -impl LookupHost { - fn new(host: String) -> io::Result<LookupHost> { - Err(io::Error::new(io::ErrorKind::Uncategorized, NonIpSockAddr { host })) - } - - pub fn port(&self) -> u16 { - self.0 - } -} - -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - self.0 - } -} - -impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(v: &str) -> io::Result<LookupHost> { - LookupHost::new(v.to_owned()) - } -} - -impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> { - LookupHost::new(format!("{host}:{port}")) - } -} - -#[allow(bad_style)] -pub mod netc { - pub const AF_INET: u8 = 0; - pub const AF_INET6: u8 = 1; - pub type sa_family_t = u8; - - #[derive(Copy, Clone)] - pub struct in_addr { - pub s_addr: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in { - #[allow(dead_code)] - pub sin_family: sa_family_t, - pub sin_port: u16, - pub sin_addr: in_addr, - } - - #[derive(Copy, Clone)] - pub struct in6_addr { - pub s6_addr: [u8; 16], - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in6 { - #[allow(dead_code)] - pub sin6_family: sa_family_t, - pub sin6_port: u16, - pub sin6_addr: in6_addr, - pub sin6_flowinfo: u32, - pub sin6_scope_id: u32, - } -} diff --git a/library/std/src/sys/pal/solid/error.rs b/library/std/src/sys/pal/solid/error.rs index e092497856d..b399463c0c2 100644 --- a/library/std/src/sys/pal/solid/error.rs +++ b/library/std/src/sys/pal/solid/error.rs @@ -1,6 +1,7 @@ pub use self::itron::error::{ItronError as SolidError, expect_success}; -use super::{abi, itron, net}; +use super::{abi, itron}; use crate::io::ErrorKind; +use crate::sys::net; /// Describe the specified SOLID error code. Returns `None` if it's an /// undefined error code. diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index d41042be518..caf848a4e9b 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -24,7 +24,6 @@ pub mod env; pub(crate) mod error; pub mod fs; pub mod io; -pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; @@ -51,7 +50,7 @@ pub fn unsupported_err() -> crate::io::Error { #[inline] pub fn is_interrupted(code: i32) -> bool { - net::is_interrupted(code) + crate::sys::net::is_interrupted(code) } pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind { diff --git a/library/std/src/sys/pal/solid/net.rs b/library/std/src/sys/pal/solid/net.rs deleted file mode 100644 index 5f6436807e2..00000000000 --- a/library/std/src/sys/pal/solid/net.rs +++ /dev/null @@ -1,425 +0,0 @@ -use libc::{c_int, c_void, size_t}; - -use self::netc::{MSG_PEEK, sockaddr, socklen_t}; -use super::abi; -use crate::ffi::CStr; -use crate::io::{self, BorrowedBuf, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut}; -use crate::net::{Shutdown, SocketAddr}; -use crate::os::solid::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd}; -use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; -use crate::sys_common::{FromInner, IntoInner}; -use crate::time::Duration; -use crate::{cmp, mem, ptr, str}; - -pub mod netc { - pub use super::super::abi::sockets::*; -} - -pub type wrlen_t = size_t; - -const READ_LIMIT: usize = libc::ssize_t::MAX as usize; - -const fn max_iov() -> usize { - // Judging by the source code, it's unlimited, but specify a lower - // value just in case. - 1024 -} - -#[doc(hidden)] -pub trait IsMinusOne { - fn is_minus_one(&self) -> bool; -} - -macro_rules! impl_is_minus_one { - ($($t:ident)*) => ($(impl IsMinusOne for $t { - fn is_minus_one(&self) -> bool { - *self == -1 - } - })*) -} - -impl_is_minus_one! { i8 i16 i32 i64 isize } - -pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> { - if t.is_minus_one() { Err(last_error()) } else { Ok(t) } -} - -/// A variant of `cvt` for `getaddrinfo` which return 0 for a success. -pub fn cvt_gai(err: c_int) -> io::Result<()> { - if err == 0 { - Ok(()) - } else { - let msg: &dyn crate::fmt::Display = match err { - netc::EAI_NONAME => &"name or service not known", - netc::EAI_SERVICE => &"service not supported", - netc::EAI_FAIL => &"non-recoverable failure in name resolution", - netc::EAI_MEMORY => &"memory allocation failure", - netc::EAI_FAMILY => &"family not supported", - _ => &err, - }; - Err(io::Error::new( - io::ErrorKind::Uncategorized, - &format!("failed to lookup address information: {msg}")[..], - )) - } -} - -/// Just to provide the same interface as sys/pal/unix/net.rs -pub fn cvt_r<T, F>(mut f: F) -> io::Result<T> -where - T: IsMinusOne, - F: FnMut() -> T, -{ - cvt(f()) -} - -/// Returns the last error from the network subsystem. -fn last_error() -> io::Error { - io::Error::from_raw_os_error(unsafe { netc::SOLID_NET_GetLastError() }) -} - -pub(super) fn error_name(er: abi::ER) -> Option<&'static str> { - unsafe { CStr::from_ptr(netc::strerror(er)) }.to_str().ok() -} - -#[inline] -pub fn is_interrupted(er: abi::ER) -> bool { - er == netc::SOLID_NET_ERR_BASE - libc::EINTR -} - -pub(super) fn decode_error_kind(er: abi::ER) -> ErrorKind { - let errno = netc::SOLID_NET_ERR_BASE - er; - match errno as libc::c_int { - libc::ECONNREFUSED => ErrorKind::ConnectionRefused, - libc::ECONNRESET => ErrorKind::ConnectionReset, - libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied, - libc::EPIPE => ErrorKind::BrokenPipe, - libc::ENOTCONN => ErrorKind::NotConnected, - libc::ECONNABORTED => ErrorKind::ConnectionAborted, - libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, - libc::EADDRINUSE => ErrorKind::AddrInUse, - libc::ENOENT => ErrorKind::NotFound, - libc::EINTR => ErrorKind::Interrupted, - libc::EINVAL => ErrorKind::InvalidInput, - libc::ETIMEDOUT => ErrorKind::TimedOut, - libc::EEXIST => ErrorKind::AlreadyExists, - libc::ENOSYS => ErrorKind::Unsupported, - libc::ENOMEM => ErrorKind::OutOfMemory, - libc::EAGAIN => ErrorKind::WouldBlock, - - _ => ErrorKind::Uncategorized, - } -} - -pub fn init() {} - -pub struct Socket(OwnedFd); - -impl Socket { - pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> { - let fam = match *addr { - SocketAddr::V4(..) => netc::AF_INET, - SocketAddr::V6(..) => netc::AF_INET6, - }; - Socket::new_raw(fam, ty) - } - - pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> { - unsafe { - let fd = cvt(netc::socket(fam, ty, 0))?; - Ok(Self::from_raw_fd(fd)) - } - } - - pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { - let (addr, len) = addr.into_inner(); - cvt(unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?; - Ok(()) - } - - pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { - self.set_nonblocking(true)?; - let r = self.connect(addr); - self.set_nonblocking(false)?; - - match r { - Ok(_) => return Ok(()), - // there's no ErrorKind for EINPROGRESS - Err(ref e) if e.raw_os_error() == Some(netc::EINPROGRESS) => {} - Err(e) => return Err(e), - } - - if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let mut timeout = - netc::timeval { tv_sec: timeout.as_secs() as _, tv_usec: timeout.subsec_micros() as _ }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - - let fds = netc::fd_set { num_fds: 1, fds: [self.as_raw_fd()] }; - - let mut writefds = fds; - let mut errorfds = fds; - - let n = unsafe { - cvt(netc::select( - self.as_raw_fd() + 1, - ptr::null_mut(), - &mut writefds, - &mut errorfds, - &mut timeout, - ))? - }; - - match n { - 0 => Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")), - _ => { - let can_write = writefds.num_fds != 0; - if !can_write { - if let Some(e) = self.take_error()? { - return Err(e); - } - } - Ok(()) - } - } - } - - pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> { - let fd = cvt_r(|| unsafe { netc::accept(self.as_raw_fd(), storage, len) })?; - unsafe { Ok(Self::from_raw_fd(fd)) } - } - - pub fn duplicate(&self) -> io::Result<Socket> { - Ok(Self(self.0.try_clone()?)) - } - - fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { - let ret = cvt(unsafe { - netc::recv(self.as_raw_fd(), buf.as_mut().as_mut_ptr().cast(), buf.capacity(), flags) - })?; - unsafe { - buf.advance_unchecked(ret as usize); - } - Ok(()) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), 0)?; - Ok(buf.len()) - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), MSG_PEEK)?; - Ok(buf.len()) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.recv_with_flags(buf, 0) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - let ret = cvt(unsafe { - netc::readv( - self.as_raw_fd(), - bufs.as_ptr() as *const netc::iovec, - cmp::min(bufs.len(), max_iov()) as c_int, - ) - })?; - Ok(ret as usize) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - true - } - - fn recv_from_with_flags( - &self, - buf: &mut [u8], - flags: c_int, - ) -> io::Result<(usize, SocketAddr)> { - let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; - - let n = cvt(unsafe { - netc::recvfrom( - self.as_raw_fd(), - buf.as_mut_ptr() as *mut c_void, - buf.len(), - flags, - &mut storage as *mut _ as *mut _, - &mut addrlen, - ) - })?; - Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?)) - } - - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, 0) - } - - pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, MSG_PEEK) - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - let ret = cvt(unsafe { - netc::write( - self.as_raw_fd(), - buf.as_ptr() as *const c_void, - cmp::min(buf.len(), READ_LIMIT), - ) - })?; - Ok(ret as usize) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let ret = cvt(unsafe { - netc::writev( - self.as_raw_fd(), - bufs.as_ptr() as *const netc::iovec, - cmp::min(bufs.len(), max_iov()) as c_int, - ) - })?; - Ok(ret as usize) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - true - } - - pub fn set_timeout(&self, dur: Option<Duration>, kind: c_int) -> io::Result<()> { - let timeout = match dur { - Some(dur) => { - if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let secs = if dur.as_secs() > netc::c_long::MAX as u64 { - netc::c_long::MAX - } else { - dur.as_secs() as netc::c_long - }; - let mut timeout = netc::timeval { tv_sec: secs, tv_usec: dur.subsec_micros() as _ }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => netc::timeval { tv_sec: 0, tv_usec: 0 }, - }; - setsockopt(self, netc::SOL_SOCKET, kind, timeout) - } - - pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> { - let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?; - if raw.tv_sec == 0 && raw.tv_usec == 0 { - Ok(None) - } else { - let sec = raw.tv_sec as u64; - let nsec = (raw.tv_usec as u32) * 1000; - Ok(Some(Duration::new(sec, nsec))) - } - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - let how = match how { - Shutdown::Write => netc::SHUT_WR, - Shutdown::Read => netc::SHUT_RD, - Shutdown::Both => netc::SHUT_RDWR, - }; - cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?; - Ok(()) - } - - pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { - let linger = netc::linger { - l_onoff: linger.is_some() as netc::c_int, - l_linger: linger.unwrap_or_default().as_secs() as netc::c_int, - }; - - setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - let val: netc::linger = getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)?; - - Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) - } - - pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { - setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, nodelay as c_int) - } - - pub fn nodelay(&self) -> io::Result<bool> { - let raw: c_int = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?; - Ok(raw != 0) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut nonblocking = nonblocking as c_int; - cvt(unsafe { - netc::ioctl(self.as_raw_fd(), netc::FIONBIO, (&mut nonblocking) as *mut c_int as _) - }) - .map(drop) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - let raw: c_int = getsockopt(self, netc::SOL_SOCKET, netc::SO_ERROR)?; - if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } - } - - // This method is used by sys_common code to abstract over targets. - pub fn as_raw(&self) -> c_int { - self.as_raw_fd() - } -} - -impl FromInner<OwnedFd> for Socket { - #[inline] - fn from_inner(sock: OwnedFd) -> Socket { - Socket(sock) - } -} - -impl IntoInner<OwnedFd> for Socket { - #[inline] - fn into_inner(self) -> OwnedFd { - self.0 - } -} - -impl AsFd for Socket { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> c_int { - self.0.as_raw_fd() - } -} - -impl FromRawFd for Socket { - #[inline] - unsafe fn from_raw_fd(fd: c_int) -> Socket { - unsafe { Self(FromRawFd::from_raw_fd(fd)) } - } -} - -impl IntoRawFd for Socket { - #[inline] - fn into_raw_fd(self) -> c_int { - self.0.into_raw_fd() - } -} diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index a9900f55b19..a9904e66664 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -15,7 +15,6 @@ pub mod env; pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; -pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys/pal/teeos/net.rs b/library/std/src/sys/pal/teeos/net.rs deleted file mode 100644 index fed95205027..00000000000 --- a/library/std/src/sys/pal/teeos/net.rs +++ /dev/null @@ -1,369 +0,0 @@ -use crate::fmt; -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; -use crate::sys::unsupported; -use crate::time::Duration; - -pub struct TcpStream(!); - -impl TcpStream { - pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - unsupported() - } - - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { - unsupported() - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> { - self.0 - } - - pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - self.0 - } - - pub fn is_read_vectored(&self) -> bool { - self.0 - } - - pub fn write(&self, _: &[u8]) -> io::Result<usize> { - self.0 - } - - pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> { - self.0 - } - - pub fn is_write_vectored(&self) -> bool { - self.0 - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - self.0 - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - self.0 - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn nodelay(&self) -> io::Result<bool> { - self.0 - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn ttl(&self) -> io::Result<u32> { - self.0 - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - self.0 - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - self.0 - } -} - -impl fmt::Debug for TcpStream { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 - } -} - -pub struct TcpListener(!); - -impl TcpListener { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - unsupported() - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - self.0 - } - - pub fn duplicate(&self) -> io::Result<TcpListener> { - self.0 - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn ttl(&self) -> io::Result<u32> { - self.0 - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn only_v6(&self) -> io::Result<bool> { - self.0 - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - self.0 - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - self.0 - } -} - -impl fmt::Debug for TcpListener { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 - } -} - -pub struct UdpSocket(!); - -impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - unsupported() - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.0 - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.0 - } - - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { - self.0 - } - - pub fn duplicate(&self) -> io::Result<UdpSocket> { - self.0 - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn broadcast(&self) -> io::Result<bool> { - self.0 - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - self.0 - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - self.0 - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - self.0 - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - self.0 - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - self.0 - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - self.0 - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - self.0 - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn ttl(&self) -> io::Result<u32> { - self.0 - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - self.0 - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn send(&self, _: &[u8]) -> io::Result<usize> { - self.0 - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - self.0 - } -} - -impl fmt::Debug for UdpSocket { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 - } -} - -pub struct LookupHost(!); - -impl LookupHost { - pub fn port(&self) -> u16 { - self.0 - } -} - -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - self.0 - } -} - -impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(_v: &str) -> io::Result<LookupHost> { - unsupported() - } -} - -impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> { - unsupported() - } -} - -#[allow(nonstandard_style)] -pub mod netc { - pub const AF_INET: u8 = 0; - pub const AF_INET6: u8 = 1; - pub type sa_family_t = u8; - - #[derive(Copy, Clone)] - pub struct in_addr { - pub s_addr: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in { - pub sin_family: sa_family_t, - pub sin_port: u16, - pub sin_addr: in_addr, - } - - #[derive(Copy, Clone)] - pub struct in6_addr { - pub s6_addr: [u8; 16], - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in6 { - pub sin6_family: sa_family_t, - pub sin6_port: u16, - pub sin6_addr: in6_addr, - pub sin6_flowinfo: u32, - pub sin6_scope_id: u32, - } -} - -pub type Socket = UdpSocket; diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index 111bed7a7eb..07025a304bf 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -19,8 +19,6 @@ pub mod fs; pub mod helpers; #[path = "../unsupported/io.rs"] pub mod io; -#[path = "../unsupported/net.rs"] -pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys/pal/unix/l4re.rs b/library/std/src/sys/pal/unix/l4re.rs deleted file mode 100644 index 37dd370c514..00000000000 --- a/library/std/src/sys/pal/unix/l4re.rs +++ /dev/null @@ -1,564 +0,0 @@ -macro_rules! unimpl { - () => { - return Err(io::const_error!( - io::ErrorKind::Unsupported, - "No networking available on L4Re.", - )); - }; -} - -pub mod net { - #![allow(warnings)] - use crate::fmt; - use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; - use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; - use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; - use crate::sys::fd::FileDesc; - use crate::sys_common::{AsInner, FromInner, IntoInner}; - use crate::time::Duration; - - #[allow(unused_extern_crates)] - pub extern crate libc as netc; - - pub struct Socket(FileDesc); - impl Socket { - pub fn new(_: &SocketAddr, _: libc::c_int) -> io::Result<Socket> { - unimpl!(); - } - - pub fn new_raw(_: libc::c_int, _: libc::c_int) -> io::Result<Socket> { - unimpl!(); - } - - pub fn new_pair(_: libc::c_int, _: libc::c_int) -> io::Result<(Socket, Socket)> { - unimpl!(); - } - - pub fn connect_timeout(&self, _: &SocketAddr, _: Duration) -> io::Result<()> { - unimpl!(); - } - - pub fn accept( - &self, - _: *mut libc::sockaddr, - _: *mut libc::socklen_t, - ) -> io::Result<Socket> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result<Socket> { - unimpl!(); - } - - pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn read_buf(&self, _: BorrowedCursor<'_>) -> io::Result<()> { - unimpl!(); - } - - pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - unimpl!(); - } - - pub fn is_read_vectored(&self) -> bool { - false - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn write(&self, _: &[u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> { - unimpl!(); - } - - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn set_timeout(&self, _: Option<Duration>, _: libc::c_int) -> io::Result<()> { - unimpl!(); - } - - pub fn timeout(&self, _: libc::c_int) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - unimpl!(); - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn nodelay(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimpl!(); - } - - // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> RawFd { - self.as_raw_fd() - } - } - - impl AsInner<FileDesc> for Socket { - #[inline] - fn as_inner(&self) -> &FileDesc { - &self.0 - } - } - - impl FromInner<FileDesc> for Socket { - fn from_inner(file_desc: FileDesc) -> Socket { - Socket(file_desc) - } - } - - impl IntoInner<FileDesc> for Socket { - fn into_inner(self) -> FileDesc { - self.0 - } - } - - impl AsFd for Socket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } - } - - impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } - } - - impl IntoRawFd for Socket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } - } - - impl FromRawFd for Socket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self(FromRawFd::from_raw_fd(raw_fd)) - } - } - - pub struct TcpStream { - inner: Socket, - } - - impl TcpStream { - pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - unimpl!(); - } - - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { - unimpl!(); - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn read_buf(&self, _: BorrowedCursor<'_>) -> io::Result<()> { - unimpl!(); - } - - pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - unimpl!(); - } - - pub fn is_read_vectored(&self) -> bool { - false - } - - pub fn write(&self, _: &[u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> { - unimpl!(); - } - - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - unimpl!(); - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn nodelay(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner<Socket> for TcpStream { - fn from_inner(socket: Socket) -> TcpStream { - TcpStream { inner: socket } - } - } - - impl fmt::Debug for TcpStream { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "No networking support available on L4Re") - } - } - - pub struct TcpListener { - inner: Socket, - } - - impl TcpListener { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - unimpl!(); - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result<TcpListener> { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn only_v6(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner<Socket> for TcpListener { - fn from_inner(socket: Socket) -> TcpListener { - TcpListener { inner: socket } - } - } - - impl fmt::Debug for TcpListener { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "No networking support available on L4Re.") - } - } - - pub struct UdpSocket { - inner: Socket, - } - - impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - unimpl!(); - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result<UdpSocket> { - unimpl!(); - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn broadcast(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unimpl!(); - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unimpl!(); - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn send(&self, _: &[u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner<Socket> for UdpSocket { - fn from_inner(socket: Socket) -> UdpSocket { - UdpSocket { inner: socket } - } - } - - impl fmt::Debug for UdpSocket { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "No networking support on L4Re available.") - } - } - - pub struct LookupHost { - original: *mut libc::addrinfo, - cur: *mut libc::addrinfo, - } - - impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - None - } - } - - impl LookupHost { - pub fn port(&self) -> u16 { - 0 // unimplemented - } - } - - unsafe impl Sync for LookupHost {} - unsafe impl Send for LookupHost {} - - impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(_v: &str) -> io::Result<LookupHost> { - unimpl!(); - } - } - - impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> { - unimpl!(); - } - } -} diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 3cc1cae8d00..6862399b942 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -14,14 +14,8 @@ pub mod futex; pub mod io; #[cfg(any(target_os = "linux", target_os = "android"))] pub mod kernel_copy; -#[cfg(target_os = "l4re")] -mod l4re; #[cfg(target_os = "linux")] pub mod linux; -#[cfg(not(target_os = "l4re"))] -pub mod net; -#[cfg(target_os = "l4re")] -pub use self::l4re::net; pub mod os; pub mod pipe; pub mod process; diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs deleted file mode 100644 index d73b9fd5eb8..00000000000 --- a/library/std/src/sys/pal/unix/net.rs +++ /dev/null @@ -1,651 +0,0 @@ -use libc::{MSG_PEEK, c_int, c_void, size_t, sockaddr, socklen_t}; - -use crate::ffi::CStr; -use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Shutdown, SocketAddr}; -use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; -use crate::sys::fd::FileDesc; -use crate::sys::pal::unix::IsMinusOne; -use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::{Duration, Instant}; -use crate::{cmp, mem}; - -cfg_if::cfg_if! { - if #[cfg(target_vendor = "apple")] { - use libc::SO_LINGER_SEC as SO_LINGER; - } else { - use libc::SO_LINGER; - } -} - -pub use crate::sys::{cvt, cvt_r}; - -#[allow(unused_extern_crates)] -pub extern crate libc as netc; - -pub type wrlen_t = size_t; - -pub struct Socket(FileDesc); - -pub fn init() {} - -pub fn cvt_gai(err: c_int) -> io::Result<()> { - if err == 0 { - return Ok(()); - } - - // We may need to trigger a glibc workaround. See on_resolver_failure() for details. - on_resolver_failure(); - - #[cfg(not(any(target_os = "espidf", target_os = "nuttx")))] - if err == libc::EAI_SYSTEM { - return Err(io::Error::last_os_error()); - } - - #[cfg(not(any(target_os = "espidf", target_os = "nuttx")))] - let detail = unsafe { - // We can't always expect a UTF-8 environment. When we don't get that luxury, - // it's better to give a low-quality error message than none at all. - CStr::from_ptr(libc::gai_strerror(err)).to_string_lossy() - }; - - #[cfg(any(target_os = "espidf", target_os = "nuttx"))] - let detail = ""; - - Err(io::Error::new( - io::ErrorKind::Uncategorized, - &format!("failed to lookup address information: {detail}")[..], - )) -} - -impl Socket { - pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> { - let fam = match *addr { - SocketAddr::V4(..) => libc::AF_INET, - SocketAddr::V6(..) => libc::AF_INET6, - }; - Socket::new_raw(fam, ty) - } - - pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> { - unsafe { - cfg_if::cfg_if! { - if #[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "hurd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "nto", - target_os = "solaris", - ))] { - // On platforms that support it we pass the SOCK_CLOEXEC - // flag to atomically create the socket and set it as - // CLOEXEC. On Linux this was added in 2.6.27. - let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?; - let socket = Socket(FileDesc::from_raw_fd(fd)); - - // DragonFlyBSD, FreeBSD and NetBSD use `SO_NOSIGPIPE` as a `setsockopt` - // flag to disable `SIGPIPE` emission on socket. - #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "dragonfly"))] - setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?; - - Ok(socket) - } else { - let fd = cvt(libc::socket(fam, ty, 0))?; - let fd = FileDesc::from_raw_fd(fd); - fd.set_cloexec()?; - let socket = Socket(fd); - - // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt` - // flag to disable `SIGPIPE` emission on socket. - #[cfg(target_vendor = "apple")] - setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?; - - Ok(socket) - } - } - } - } - - #[cfg(not(target_os = "vxworks"))] - pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> { - unsafe { - let mut fds = [0, 0]; - - cfg_if::cfg_if! { - if #[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux", - target_os = "hurd", - target_os = "netbsd", - target_os = "openbsd", - target_os = "nto", - ))] { - // Like above, set cloexec atomically - cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; - Ok((Socket(FileDesc::from_raw_fd(fds[0])), Socket(FileDesc::from_raw_fd(fds[1])))) - } else { - cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?; - let a = FileDesc::from_raw_fd(fds[0]); - let b = FileDesc::from_raw_fd(fds[1]); - a.set_cloexec()?; - b.set_cloexec()?; - Ok((Socket(a), Socket(b))) - } - } - } - } - - #[cfg(target_os = "vxworks")] - pub fn new_pair(_fam: c_int, _ty: c_int) -> io::Result<(Socket, Socket)> { - unimplemented!() - } - - pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { - let (addr, len) = addr.into_inner(); - loop { - let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) }; - if result.is_minus_one() { - let err = crate::sys::os::errno(); - match err { - libc::EINTR => continue, - libc::EISCONN => return Ok(()), - _ => return Err(io::Error::from_raw_os_error(err)), - } - } - return Ok(()); - } - } - - pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { - self.set_nonblocking(true)?; - let r = unsafe { - let (addr, len) = addr.into_inner(); - cvt(libc::connect(self.as_raw_fd(), addr.as_ptr(), len)) - }; - self.set_nonblocking(false)?; - - match r { - Ok(_) => return Ok(()), - // there's no ErrorKind for EINPROGRESS :( - Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {} - Err(e) => return Err(e), - } - - let mut pollfd = libc::pollfd { fd: self.as_raw_fd(), events: libc::POLLOUT, revents: 0 }; - - if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let start = Instant::now(); - - loop { - let elapsed = start.elapsed(); - if elapsed >= timeout { - return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); - } - - let timeout = timeout - elapsed; - let mut timeout = timeout - .as_secs() - .saturating_mul(1_000) - .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000); - if timeout == 0 { - timeout = 1; - } - - let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; - - match unsafe { libc::poll(&mut pollfd, 1, timeout) } { - -1 => { - let err = io::Error::last_os_error(); - if !err.is_interrupted() { - return Err(err); - } - } - 0 => {} - _ => { - if cfg!(target_os = "vxworks") { - // VxWorks poll does not return POLLHUP or POLLERR in revents. Check if the - // connection actually succeeded and return ok only when the socket is - // ready and no errors were found. - if let Some(e) = self.take_error()? { - return Err(e); - } - } else { - // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look - // for POLLHUP or POLLERR rather than read readiness - if pollfd.revents & (libc::POLLHUP | libc::POLLERR) != 0 { - let e = self.take_error()?.unwrap_or_else(|| { - io::const_error!( - io::ErrorKind::Uncategorized, - "no error set after POLLHUP", - ) - }); - return Err(e); - } - } - - return Ok(()); - } - } - } - } - - pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> { - // Unfortunately the only known way right now to accept a socket and - // atomically set the CLOEXEC flag is to use the `accept4` syscall on - // platforms that support it. On Linux, this was added in 2.6.28, - // glibc 2.10 and musl 0.9.5. - cfg_if::cfg_if! { - if #[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux", - target_os = "hurd", - target_os = "netbsd", - target_os = "openbsd", - ))] { - unsafe { - let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?; - Ok(Socket(FileDesc::from_raw_fd(fd))) - } - } else { - unsafe { - let fd = cvt_r(|| libc::accept(self.as_raw_fd(), storage, len))?; - let fd = FileDesc::from_raw_fd(fd); - fd.set_cloexec()?; - Ok(Socket(fd)) - } - } - } - } - - pub fn duplicate(&self) -> io::Result<Socket> { - self.0.duplicate().map(Socket) - } - - fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { - let ret = cvt(unsafe { - libc::recv( - self.as_raw_fd(), - buf.as_mut().as_mut_ptr() as *mut c_void, - buf.capacity(), - flags, - ) - })?; - unsafe { - buf.advance_unchecked(ret as usize); - } - Ok(()) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), 0)?; - Ok(buf.len()) - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), MSG_PEEK)?; - Ok(buf.len()) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.recv_with_flags(buf, 0) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - self.0.read_vectored(bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - self.0.is_read_vectored() - } - - fn recv_from_with_flags( - &self, - buf: &mut [u8], - flags: c_int, - ) -> io::Result<(usize, SocketAddr)> { - let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t; - - let n = cvt(unsafe { - libc::recvfrom( - self.as_raw_fd(), - buf.as_mut_ptr() as *mut c_void, - buf.len(), - flags, - (&raw mut storage) as *mut _, - &mut addrlen, - ) - })?; - Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?)) - } - - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, 0) - } - - #[cfg(any(target_os = "android", target_os = "linux"))] - pub fn recv_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> { - let n = cvt(unsafe { libc::recvmsg(self.as_raw_fd(), msg, libc::MSG_CMSG_CLOEXEC) })?; - Ok(n as usize) - } - - pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, MSG_PEEK) - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - self.0.write_vectored(bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - self.0.is_write_vectored() - } - - #[cfg(any(target_os = "android", target_os = "linux"))] - pub fn send_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> { - let n = cvt(unsafe { libc::sendmsg(self.as_raw_fd(), msg, 0) })?; - Ok(n as usize) - } - - pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> { - let timeout = match dur { - Some(dur) => { - if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let secs = if dur.as_secs() > libc::time_t::MAX as u64 { - libc::time_t::MAX - } else { - dur.as_secs() as libc::time_t - }; - let mut timeout = libc::timeval { - tv_sec: secs, - tv_usec: dur.subsec_micros() as libc::suseconds_t, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => libc::timeval { tv_sec: 0, tv_usec: 0 }, - }; - setsockopt(self, libc::SOL_SOCKET, kind, timeout) - } - - pub fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> { - let raw: libc::timeval = getsockopt(self, libc::SOL_SOCKET, kind)?; - if raw.tv_sec == 0 && raw.tv_usec == 0 { - Ok(None) - } else { - let sec = raw.tv_sec as u64; - let nsec = (raw.tv_usec as u32) * 1000; - Ok(Some(Duration::new(sec, nsec))) - } - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - let how = match how { - Shutdown::Write => libc::SHUT_WR, - Shutdown::Read => libc::SHUT_RD, - Shutdown::Both => libc::SHUT_RDWR, - }; - cvt(unsafe { libc::shutdown(self.as_raw_fd(), how) })?; - Ok(()) - } - - pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { - let linger = libc::linger { - l_onoff: linger.is_some() as libc::c_int, - l_linger: linger.unwrap_or_default().as_secs() as libc::c_int, - }; - - setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - let val: libc::linger = getsockopt(self, libc::SOL_SOCKET, SO_LINGER)?; - - Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) - } - - pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { - setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int) - } - - pub fn nodelay(&self) -> io::Result<bool> { - let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)?; - Ok(raw != 0) - } - - #[cfg(any(target_os = "android", target_os = "linux",))] - pub fn set_quickack(&self, quickack: bool) -> io::Result<()> { - setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int) - } - - #[cfg(any(target_os = "android", target_os = "linux",))] - pub fn quickack(&self) -> io::Result<bool> { - let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)?; - Ok(raw != 0) - } - - // bionic libc makes no use of this flag - #[cfg(target_os = "linux")] - pub fn set_deferaccept(&self, accept: u32) -> io::Result<()> { - setsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT, accept as c_int) - } - - #[cfg(target_os = "linux")] - pub fn deferaccept(&self) -> io::Result<u32> { - let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT)?; - Ok(raw as u32) - } - - #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] - pub fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> { - if !name.to_bytes().is_empty() { - const AF_NAME_MAX: usize = 16; - let mut buf = [0; AF_NAME_MAX]; - for (src, dst) in name.to_bytes().iter().zip(&mut buf[..AF_NAME_MAX - 1]) { - *dst = *src as libc::c_char; - } - let mut arg: libc::accept_filter_arg = unsafe { mem::zeroed() }; - arg.af_name = buf; - setsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER, &mut arg) - } else { - setsockopt( - self, - libc::SOL_SOCKET, - libc::SO_ACCEPTFILTER, - core::ptr::null_mut() as *mut c_void, - ) - } - } - - #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] - pub fn acceptfilter(&self) -> io::Result<&CStr> { - let arg: libc::accept_filter_arg = - getsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER)?; - let s: &[u8] = - unsafe { core::slice::from_raw_parts(arg.af_name.as_ptr() as *const u8, 16) }; - let name = CStr::from_bytes_with_nul(s).unwrap(); - Ok(name) - } - - #[cfg(any(target_os = "android", target_os = "linux",))] - pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { - setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int) - } - - #[cfg(any(target_os = "android", target_os = "linux",))] - pub fn passcred(&self) -> io::Result<bool> { - let passcred: libc::c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)?; - Ok(passcred != 0) - } - - #[cfg(target_os = "netbsd")] - pub fn set_local_creds(&self, local_creds: bool) -> io::Result<()> { - setsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS, local_creds as libc::c_int) - } - - #[cfg(target_os = "netbsd")] - pub fn local_creds(&self) -> io::Result<bool> { - let local_creds: libc::c_int = getsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS)?; - Ok(local_creds != 0) - } - - #[cfg(target_os = "freebsd")] - pub fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()> { - setsockopt( - self, - libc::AF_LOCAL, - libc::LOCAL_CREDS_PERSISTENT, - local_creds_persistent as libc::c_int, - ) - } - - #[cfg(target_os = "freebsd")] - pub fn local_creds_persistent(&self) -> io::Result<bool> { - let local_creds_persistent: libc::c_int = - getsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT)?; - Ok(local_creds_persistent != 0) - } - - #[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "vita")))] - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut nonblocking = nonblocking as libc::c_int; - cvt(unsafe { libc::ioctl(self.as_raw_fd(), libc::FIONBIO, &mut nonblocking) }).map(drop) - } - - #[cfg(target_os = "vita")] - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let option = nonblocking as libc::c_int; - setsockopt(self, libc::SOL_SOCKET, libc::SO_NONBLOCK, option) - } - - #[cfg(any(target_os = "solaris", target_os = "illumos"))] - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - // FIONBIO is inadequate for sockets on illumos/Solaris, so use the - // fcntl(F_[GS]ETFL)-based method provided by FileDesc instead. - self.0.set_nonblocking(nonblocking) - } - - #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] - pub fn set_mark(&self, mark: u32) -> io::Result<()> { - #[cfg(target_os = "linux")] - let option = libc::SO_MARK; - #[cfg(target_os = "freebsd")] - let option = libc::SO_USER_COOKIE; - #[cfg(target_os = "openbsd")] - let option = libc::SO_RTABLE; - setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; - if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } - } - - // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> RawFd { - self.as_raw_fd() - } -} - -impl AsInner<FileDesc> for Socket { - #[inline] - fn as_inner(&self) -> &FileDesc { - &self.0 - } -} - -impl IntoInner<FileDesc> for Socket { - fn into_inner(self) -> FileDesc { - self.0 - } -} - -impl FromInner<FileDesc> for Socket { - fn from_inner(file_desc: FileDesc) -> Self { - Self(file_desc) - } -} - -impl AsFd for Socket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl IntoRawFd for Socket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl FromRawFd for Socket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self(FromRawFd::from_raw_fd(raw_fd)) - } -} - -// In versions of glibc prior to 2.26, there's a bug where the DNS resolver -// will cache the contents of /etc/resolv.conf, so changes to that file on disk -// can be ignored by a long-running program. That can break DNS lookups on e.g. -// laptops where the network comes and goes. See -// https://sourceware.org/bugzilla/show_bug.cgi?id=984. Note however that some -// distros including Debian have patched glibc to fix this for a long time. -// -// A workaround for this bug is to call the res_init libc function, to clear -// the cached configs. Unfortunately, while we believe glibc's implementation -// of res_init is thread-safe, we know that other implementations are not -// (https://github.com/rust-lang/rust/issues/43592). Code here in std could -// try to synchronize its res_init calls with a Mutex, but that wouldn't -// protect programs that call into libc in other ways. So instead of calling -// res_init unconditionally, we call it only when we detect we're linking -// against glibc version < 2.26. (That is, when we both know its needed and -// believe it's thread-safe). -#[cfg(all(target_os = "linux", target_env = "gnu"))] -fn on_resolver_failure() { - use crate::sys; - - // If the version fails to parse, we treat it the same as "not glibc". - if let Some(version) = sys::os::glibc_version() { - if version < (2, 26) { - unsafe { libc::res_init() }; - } - } -} - -#[cfg(not(all(target_os = "linux", target_env = "gnu")))] -fn on_resolver_failure() {} diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs index 01d516f7568..4941dd4918c 100644 --- a/library/std/src/sys/pal/unsupported/mod.rs +++ b/library/std/src/sys/pal/unsupported/mod.rs @@ -4,7 +4,6 @@ pub mod args; pub mod env; pub mod fs; pub mod io; -pub mod net; pub mod os; pub mod pipe; pub mod process; diff --git a/library/std/src/sys/pal/unsupported/net.rs b/library/std/src/sys/pal/unsupported/net.rs deleted file mode 100644 index 87e6106468f..00000000000 --- a/library/std/src/sys/pal/unsupported/net.rs +++ /dev/null @@ -1,369 +0,0 @@ -use crate::fmt; -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; -use crate::sys::unsupported; -use crate::time::Duration; - -pub struct TcpStream(!); - -impl TcpStream { - pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - unsupported() - } - - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { - unsupported() - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> { - self.0 - } - - pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - self.0 - } - - pub fn is_read_vectored(&self) -> bool { - self.0 - } - - pub fn write(&self, _: &[u8]) -> io::Result<usize> { - self.0 - } - - pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> { - self.0 - } - - pub fn is_write_vectored(&self) -> bool { - self.0 - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - self.0 - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - self.0 - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn nodelay(&self) -> io::Result<bool> { - self.0 - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn ttl(&self) -> io::Result<u32> { - self.0 - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - self.0 - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - self.0 - } -} - -impl fmt::Debug for TcpStream { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 - } -} - -pub struct TcpListener(!); - -impl TcpListener { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - unsupported() - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - self.0 - } - - pub fn duplicate(&self) -> io::Result<TcpListener> { - self.0 - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn ttl(&self) -> io::Result<u32> { - self.0 - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn only_v6(&self) -> io::Result<bool> { - self.0 - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - self.0 - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - self.0 - } -} - -impl fmt::Debug for TcpListener { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 - } -} - -pub struct UdpSocket(!); - -impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - unsupported() - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - self.0 - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.0 - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.0 - } - - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { - self.0 - } - - pub fn duplicate(&self) -> io::Result<UdpSocket> { - self.0 - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - self.0 - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - self.0 - } - - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn broadcast(&self) -> io::Result<bool> { - self.0 - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - self.0 - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - self.0 - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - self.0 - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - self.0 - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - self.0 - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - self.0 - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - self.0 - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - self.0 - } - - pub fn ttl(&self) -> io::Result<u32> { - self.0 - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - self.0 - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - self.0 - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - self.0 - } - - pub fn send(&self, _: &[u8]) -> io::Result<usize> { - self.0 - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - self.0 - } -} - -impl fmt::Debug for UdpSocket { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 - } -} - -pub struct LookupHost(!); - -impl LookupHost { - pub fn port(&self) -> u16 { - self.0 - } -} - -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - self.0 - } -} - -impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(_v: &str) -> io::Result<LookupHost> { - unsupported() - } -} - -impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> { - unsupported() - } -} - -#[allow(nonstandard_style)] -pub mod netc { - pub const AF_INET: u8 = 0; - pub const AF_INET6: u8 = 1; - pub type sa_family_t = u8; - - #[derive(Copy, Clone)] - pub struct in_addr { - pub s_addr: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in { - #[allow(dead_code)] - pub sin_family: sa_family_t, - pub sin_port: u16, - pub sin_addr: in_addr, - } - - #[derive(Copy, Clone)] - pub struct in6_addr { - pub s6_addr: [u8; 16], - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in6 { - #[allow(dead_code)] - pub sin6_family: sa_family_t, - pub sin6_port: u16, - pub sin6_addr: in6_addr, - pub sin6_flowinfo: u32, - pub sin6_scope_id: u32, - } -} diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index 361802d101d..312ad28ab51 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -22,7 +22,6 @@ pub mod fs; pub mod futex; pub mod io; -pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; @@ -45,5 +44,4 @@ mod helpers; // import conflict rules. If we glob export `helpers` and `common` together, // then the compiler complains about conflicts. -use helpers::err2io; -pub use helpers::{abort_internal, decode_error_kind, is_interrupted}; +pub(crate) use helpers::{abort_internal, decode_error_kind, err2io, is_interrupted}; diff --git a/library/std/src/sys/pal/wasi/net.rs b/library/std/src/sys/pal/wasi/net.rs deleted file mode 100644 index a6486799828..00000000000 --- a/library/std/src/sys/pal/wasi/net.rs +++ /dev/null @@ -1,543 +0,0 @@ -#![forbid(unsafe_op_in_unsafe_fn)] - -use super::err2io; -use super::fd::WasiFd; -use crate::fmt; -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; -use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; -use crate::sys::unsupported; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::Duration; - -pub struct Socket(WasiFd); - -pub struct TcpStream { - inner: Socket, -} - -impl AsInner<WasiFd> for Socket { - #[inline] - fn as_inner(&self) -> &WasiFd { - &self.0 - } -} - -impl IntoInner<WasiFd> for Socket { - fn into_inner(self) -> WasiFd { - self.0 - } -} - -impl FromInner<WasiFd> for Socket { - fn from_inner(inner: WasiFd) -> Socket { - Socket(inner) - } -} - -impl AsFd for Socket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl IntoRawFd for Socket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl FromRawFd for Socket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } - } -} - -impl TcpStream { - pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - unsupported() - } - - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { - unsupported() - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - unsupported() - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - unsupported() - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unsupported() - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - self.read_vectored(&mut [IoSliceMut::new(buf)]) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.socket().as_inner().read_buf(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - self.socket().as_inner().read(bufs) - } - - pub fn is_read_vectored(&self) -> bool { - true - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - self.write_vectored(&[IoSlice::new(buf)]) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - self.socket().as_inner().write(bufs) - } - - pub fn is_write_vectored(&self) -> bool { - true - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - unsupported() - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unsupported() - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - let wasi_how = match how { - Shutdown::Read => wasi::SDFLAGS_RD, - Shutdown::Write => wasi::SDFLAGS_WR, - Shutdown::Both => wasi::SDFLAGS_RD | wasi::SDFLAGS_WR, - }; - - unsafe { wasi::sock_shutdown(self.socket().as_raw_fd() as _, wasi_how).map_err(err2io) } - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - unsupported() - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - unsupported() - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - unsupported() - } - - pub fn nodelay(&self) -> io::Result<bool> { - unsupported() - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unsupported() - } - - pub fn ttl(&self) -> io::Result<u32> { - unsupported() - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unsupported() - } - - pub fn set_nonblocking(&self, state: bool) -> io::Result<()> { - let fdstat = unsafe { - wasi::fd_fdstat_get(self.socket().as_inner().as_raw_fd() as wasi::Fd).map_err(err2io)? - }; - - let mut flags = fdstat.fs_flags; - - if state { - flags |= wasi::FDFLAGS_NONBLOCK; - } else { - flags &= !wasi::FDFLAGS_NONBLOCK; - } - - unsafe { - wasi::fd_fdstat_set_flags(self.socket().as_inner().as_raw_fd() as wasi::Fd, flags) - .map_err(err2io) - } - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } -} - -impl FromInner<Socket> for TcpStream { - fn from_inner(socket: Socket) -> TcpStream { - TcpStream { inner: socket } - } -} - -impl fmt::Debug for TcpStream { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("TcpStream").field("fd", &self.inner.as_raw_fd()).finish() - } -} - -pub struct TcpListener { - inner: Socket, -} - -impl TcpListener { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - unsupported() - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unsupported() - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - let fd = unsafe { - wasi::sock_accept(self.as_inner().as_inner().as_raw_fd() as _, 0).map_err(err2io)? - }; - - Ok(( - TcpStream::from_inner(unsafe { Socket::from_raw_fd(fd as _) }), - // WASI has no concept of SocketAddr yet - // return an unspecified IPv4Addr - SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0), - )) - } - - pub fn duplicate(&self) -> io::Result<TcpListener> { - unsupported() - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unsupported() - } - - pub fn ttl(&self) -> io::Result<u32> { - unsupported() - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - unsupported() - } - - pub fn only_v6(&self) -> io::Result<bool> { - unsupported() - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unsupported() - } - - pub fn set_nonblocking(&self, state: bool) -> io::Result<()> { - let fdstat = unsafe { - wasi::fd_fdstat_get(self.socket().as_inner().as_raw_fd() as wasi::Fd).map_err(err2io)? - }; - - let mut flags = fdstat.fs_flags; - - if state { - flags |= wasi::FDFLAGS_NONBLOCK; - } else { - flags &= !wasi::FDFLAGS_NONBLOCK; - } - - unsafe { - wasi::fd_fdstat_set_flags(self.socket().as_inner().as_raw_fd() as wasi::Fd, flags) - .map_err(err2io) - } - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } -} - -impl AsInner<Socket> for TcpListener { - #[inline] - fn as_inner(&self) -> &Socket { - &self.inner - } -} - -impl IntoInner<Socket> for TcpListener { - fn into_inner(self) -> Socket { - self.inner - } -} - -impl FromInner<Socket> for TcpListener { - fn from_inner(inner: Socket) -> TcpListener { - TcpListener { inner } - } -} - -impl fmt::Debug for TcpListener { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("TcpListener").field("fd", &self.inner.as_raw_fd()).finish() - } -} - -pub struct UdpSocket { - inner: Socket, -} - -impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - unsupported() - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - unsupported() - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unsupported() - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unsupported() - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unsupported() - } - - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { - unsupported() - } - - pub fn duplicate(&self) -> io::Result<UdpSocket> { - unsupported() - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - unsupported() - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - unsupported() - } - - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - unsupported() - } - - pub fn broadcast(&self) -> io::Result<bool> { - unsupported() - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - unsupported() - } - - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - unsupported() - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - unsupported() - } - - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - unsupported() - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - unsupported() - } - - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - unsupported() - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unsupported() - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unsupported() - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unsupported() - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unsupported() - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unsupported() - } - - pub fn ttl(&self) -> io::Result<u32> { - unsupported() - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unsupported() - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unsupported() - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { - unsupported() - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unsupported() - } - - pub fn send(&self, _: &[u8]) -> io::Result<usize> { - unsupported() - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - unsupported() - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } -} - -impl AsInner<Socket> for UdpSocket { - #[inline] - fn as_inner(&self) -> &Socket { - &self.inner - } -} - -impl IntoInner<Socket> for UdpSocket { - fn into_inner(self) -> Socket { - self.inner - } -} - -impl FromInner<Socket> for UdpSocket { - fn from_inner(inner: Socket) -> UdpSocket { - UdpSocket { inner } - } -} - -impl fmt::Debug for UdpSocket { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("UdpSocket").field("fd", &self.inner.as_raw_fd()).finish() - } -} - -pub struct LookupHost(!); - -impl LookupHost { - pub fn port(&self) -> u16 { - self.0 - } -} - -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - self.0 - } -} - -impl<'a> TryFrom<&'a str> for LookupHost { - type Error = io::Error; - - fn try_from(_v: &'a str) -> io::Result<LookupHost> { - unsupported() - } -} - -impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> { - unsupported() - } -} - -#[allow(nonstandard_style)] -pub mod netc { - pub const AF_INET: u8 = 0; - pub const AF_INET6: u8 = 1; - pub type sa_family_t = u8; - - #[derive(Copy, Clone)] - pub struct in_addr { - pub s_addr: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in { - #[allow(dead_code)] - pub sin_family: sa_family_t, - pub sin_port: u16, - pub sin_addr: in_addr, - } - - #[derive(Copy, Clone)] - pub struct in6_addr { - pub s6_addr: [u8; 16], - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in6 { - #[allow(dead_code)] - pub sin6_family: sa_family_t, - pub sin6_port: u16, - pub sin6_addr: in6_addr, - pub sin6_flowinfo: u32, - pub sin6_scope_id: u32, - } -} diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs index 320712fdcc9..234e946d3b8 100644 --- a/library/std/src/sys/pal/wasip2/mod.rs +++ b/library/std/src/sys/pal/wasip2/mod.rs @@ -20,7 +20,6 @@ pub mod futex; #[path = "../wasi/io.rs"] pub mod io; -pub mod net; #[path = "../wasi/os.rs"] pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/wasip2/net.rs b/library/std/src/sys/pal/wasip2/net.rs deleted file mode 100644 index f009a51821f..00000000000 --- a/library/std/src/sys/pal/wasip2/net.rs +++ /dev/null @@ -1,417 +0,0 @@ -#![deny(unsafe_op_in_unsafe_fn)] - -use libc::{c_int, c_void, size_t}; - -use crate::ffi::CStr; -use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Shutdown, SocketAddr}; -use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys::unsupported; -use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::{Duration, Instant}; -use crate::{cmp, mem, str}; - -pub extern crate libc as netc; - -#[allow(non_camel_case_types)] -pub type wrlen_t = size_t; - -#[doc(hidden)] -pub trait IsMinusOne { - fn is_minus_one(&self) -> bool; -} - -macro_rules! impl_is_minus_one { - ($($t:ident)*) => ($(impl IsMinusOne for $t { - fn is_minus_one(&self) -> bool { - *self == -1 - } - })*) -} - -impl_is_minus_one! { i8 i16 i32 i64 isize } - -pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> { - if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) } -} - -pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T> -where - T: IsMinusOne, - F: FnMut() -> T, -{ - loop { - match cvt(f()) { - Err(ref e) if e.is_interrupted() => {} - other => return other, - } - } -} - -pub fn cvt_gai(err: c_int) -> io::Result<()> { - if err == 0 { - return Ok(()); - } - - if err == netc::EAI_SYSTEM { - return Err(io::Error::last_os_error()); - } - - let detail = unsafe { - str::from_utf8(CStr::from_ptr(netc::gai_strerror(err)).to_bytes()).unwrap().to_owned() - }; - - Err(io::Error::new( - io::ErrorKind::Uncategorized, - &format!("failed to lookup address information: {detail}")[..], - )) -} - -pub fn init() {} - -pub struct WasiSocket(OwnedFd); - -pub struct Socket(WasiSocket); - -impl Socket { - pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> { - let fam = match *addr { - SocketAddr::V4(..) => netc::AF_INET, - SocketAddr::V6(..) => netc::AF_INET6, - }; - Socket::new_raw(fam, ty) - } - - pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> { - let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?; - Ok(unsafe { Self::from_raw_fd(fd) }) - } - - pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { - let (addr, len) = addr.into_inner(); - cvt_r(|| unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?; - Ok(()) - } - - pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { - self.set_nonblocking(true)?; - let r = self.connect(addr); - self.set_nonblocking(false)?; - - match r { - Ok(_) => return Ok(()), - // there's no ErrorKind for EINPROGRESS - Err(ref e) if e.raw_os_error() == Some(netc::EINPROGRESS) => {} - Err(e) => return Err(e), - } - - let mut pollfd = netc::pollfd { fd: self.as_raw_fd(), events: netc::POLLOUT, revents: 0 }; - - if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let start = Instant::now(); - - loop { - let elapsed = start.elapsed(); - if elapsed >= timeout { - return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); - } - - let timeout = timeout - elapsed; - let mut timeout = timeout - .as_secs() - .saturating_mul(1_000) - .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000); - if timeout == 0 { - timeout = 1; - } - - let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; - - match unsafe { netc::poll(&mut pollfd, 1, timeout) } { - -1 => { - let err = io::Error::last_os_error(); - if !err.is_interrupted() { - return Err(err); - } - } - 0 => {} - _ => { - // WASI poll does not return POLLHUP or POLLERR in revents. Check if the - // connnection actually succeeded and return ok only when the socket is - // ready and no errors were found. - if let Some(e) = self.take_error()? { - return Err(e); - } - - return Ok(()); - } - } - } - } - - pub fn accept( - &self, - storage: *mut netc::sockaddr, - len: *mut netc::socklen_t, - ) -> io::Result<Socket> { - let fd = cvt_r(|| unsafe { netc::accept(self.as_raw_fd(), storage, len) })?; - Ok(unsafe { Self::from_raw_fd(fd) }) - } - - pub fn duplicate(&self) -> io::Result<Socket> { - unsupported() - } - - fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { - let ret = cvt(unsafe { - netc::recv( - self.as_raw_fd(), - buf.as_mut().as_mut_ptr() as *mut c_void, - buf.capacity(), - flags, - ) - })?; - unsafe { - buf.advance_unchecked(ret as usize); - } - Ok(()) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), 0)?; - Ok(buf.len()) - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), netc::MSG_PEEK)?; - Ok(buf.len()) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.recv_with_flags(buf, 0) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - io::default_read_vectored(|b| self.read(b), bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - false - } - - fn recv_from_with_flags( - &self, - buf: &mut [u8], - flags: c_int, - ) -> io::Result<(usize, SocketAddr)> { - let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; - - let n = cvt(unsafe { - netc::recvfrom( - self.as_raw_fd(), - buf.as_mut_ptr() as *mut c_void, - buf.len(), - flags, - core::ptr::addr_of_mut!(storage) as *mut _, - &mut addrlen, - ) - })?; - Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?)) - } - - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, 0) - } - - pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, netc::MSG_PEEK) - } - - fn write(&self, buf: &[u8]) -> io::Result<usize> { - let len = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t; - let ret = cvt(unsafe { - netc::send(self.as_raw(), buf.as_ptr() as *const c_void, len, netc::MSG_NOSIGNAL) - })?; - Ok(ret as usize) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - io::default_write_vectored(|b| self.write(b), bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn set_timeout(&self, dur: Option<Duration>, kind: c_int) -> io::Result<()> { - let timeout = match dur { - Some(dur) => { - if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let secs = dur.as_secs().try_into().unwrap_or(netc::time_t::MAX); - let mut timeout = netc::timeval { - tv_sec: secs, - tv_usec: dur.subsec_micros() as netc::suseconds_t, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => netc::timeval { tv_sec: 0, tv_usec: 0 }, - }; - setsockopt(self, netc::SOL_SOCKET, kind, timeout) - } - - pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> { - let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?; - if raw.tv_sec == 0 && raw.tv_usec == 0 { - Ok(None) - } else { - let sec = raw.tv_sec as u64; - let nsec = (raw.tv_usec as u32) * 1000; - Ok(Some(Duration::new(sec, nsec))) - } - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - let how = match how { - Shutdown::Write => netc::SHUT_WR, - Shutdown::Read => netc::SHUT_RD, - Shutdown::Both => netc::SHUT_RDWR, - }; - cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?; - Ok(()) - } - - pub fn set_linger(&self, _linger: Option<Duration>) -> io::Result<()> { - unsupported() - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - unsupported() - } - - pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { - setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, nodelay as c_int) - } - - pub fn nodelay(&self) -> io::Result<bool> { - let raw: c_int = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?; - Ok(raw != 0) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut nonblocking = nonblocking as c_int; - cvt(unsafe { netc::ioctl(self.as_raw_fd(), netc::FIONBIO, &mut nonblocking) }).map(drop) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - let raw: c_int = getsockopt(self, netc::SOL_SOCKET, netc::SO_ERROR)?; - if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } - } - - // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> RawFd { - self.as_raw_fd() - } -} - -impl AsInner<OwnedFd> for WasiSocket { - #[inline] - fn as_inner(&self) -> &OwnedFd { - &self.0 - } -} - -impl IntoInner<OwnedFd> for WasiSocket { - fn into_inner(self) -> OwnedFd { - self.0 - } -} - -impl FromInner<OwnedFd> for WasiSocket { - fn from_inner(owned_fd: OwnedFd) -> Self { - Self(owned_fd) - } -} - -impl AsFd for WasiSocket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for WasiSocket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl IntoRawFd for WasiSocket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl FromRawFd for WasiSocket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } - } -} - -impl AsInner<WasiSocket> for Socket { - #[inline] - fn as_inner(&self) -> &WasiSocket { - &self.0 - } -} - -impl IntoInner<WasiSocket> for Socket { - fn into_inner(self) -> WasiSocket { - self.0 - } -} - -impl FromInner<WasiSocket> for Socket { - fn from_inner(sock: WasiSocket) -> Socket { - Socket(sock) - } -} - -impl AsFd for Socket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl IntoRawFd for Socket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl FromRawFd for Socket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } - } -} diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index 41fe019f110..1280f353200 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs @@ -23,8 +23,6 @@ pub mod env; pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; -#[path = "../unsupported/net.rs"] -pub mod net; #[path = "../unsupported/os.rs"] pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 4282dbb5493..f9aa049ca9a 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -22,7 +22,6 @@ pub mod fs; pub mod futex; pub mod handle; pub mod io; -pub mod net; pub mod os; pub mod pipe; pub mod process; @@ -63,7 +62,7 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) { // SAFETY: must be called only once during runtime cleanup. // NOTE: this is not guaranteed to run, for example when the program aborts. pub unsafe fn cleanup() { - net::cleanup(); + crate::sys::net::cleanup(); } #[inline] diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs deleted file mode 100644 index a92853c642c..00000000000 --- a/library/std/src/sys/pal/windows/net.rs +++ /dev/null @@ -1,574 +0,0 @@ -#![unstable(issue = "none", feature = "windows_net")] - -use core::ffi::{c_int, c_long, c_ulong, c_ushort}; - -use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut, Read}; -use crate::net::{Shutdown, SocketAddr}; -use crate::os::windows::io::{ - AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, -}; -use crate::sync::OnceLock; -use crate::sys::c; -use crate::sys_common::{AsInner, FromInner, IntoInner, net}; -use crate::time::Duration; -use crate::{cmp, mem, ptr, sys}; - -#[allow(non_camel_case_types)] -pub type wrlen_t = i32; - -pub mod netc { - //! BSD socket compatibility shim - //! - //! Some Windows API types are not quite what's expected by our cross-platform - //! net code. E.g. naming differences or different pointer types. - - use core::ffi::{c_char, c_int, c_uint, c_ulong, c_ushort, c_void}; - - use crate::sys::c::{self, ADDRESS_FAMILY, ADDRINFOA, SOCKADDR, SOCKET}; - // re-exports from Windows API bindings. - pub use crate::sys::c::{ - ADDRESS_FAMILY as sa_family_t, ADDRINFOA as addrinfo, IP_ADD_MEMBERSHIP, - IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_TTL, IPPROTO_IP, IPPROTO_IPV6, - IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_LOOP, IPV6_V6ONLY, SO_BROADCAST, - SO_RCVTIMEO, SO_SNDTIMEO, SOCK_DGRAM, SOCK_STREAM, SOCKADDR as sockaddr, - SOCKADDR_STORAGE as sockaddr_storage, SOL_SOCKET, bind, connect, freeaddrinfo, getpeername, - getsockname, getsockopt, listen, setsockopt, - }; - - #[allow(non_camel_case_types)] - pub type socklen_t = c_int; - - pub const AF_INET: i32 = c::AF_INET as i32; - pub const AF_INET6: i32 = c::AF_INET6 as i32; - - // The following two structs use a union in the generated bindings but - // our cross-platform code expects a normal field so it's redefined here. - // As a consequence, we also need to redefine other structs that use this struct. - #[repr(C)] - #[derive(Copy, Clone)] - pub struct in_addr { - pub s_addr: u32, - } - - #[repr(C)] - #[derive(Copy, Clone)] - pub struct in6_addr { - pub s6_addr: [u8; 16], - } - - #[repr(C)] - pub struct ip_mreq { - pub imr_multiaddr: in_addr, - pub imr_interface: in_addr, - } - - #[repr(C)] - pub struct ipv6_mreq { - pub ipv6mr_multiaddr: in6_addr, - pub ipv6mr_interface: c_uint, - } - - #[repr(C)] - #[derive(Copy, Clone)] - pub struct sockaddr_in { - pub sin_family: ADDRESS_FAMILY, - pub sin_port: c_ushort, - pub sin_addr: in_addr, - pub sin_zero: [c_char; 8], - } - - #[repr(C)] - #[derive(Copy, Clone)] - pub struct sockaddr_in6 { - pub sin6_family: ADDRESS_FAMILY, - pub sin6_port: c_ushort, - pub sin6_flowinfo: c_ulong, - pub sin6_addr: in6_addr, - pub sin6_scope_id: c_ulong, - } - - pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int { - unsafe { c::send(socket, buf.cast::<u8>(), len, flags) } - } - pub unsafe fn sendto( - socket: SOCKET, - buf: *const c_void, - len: c_int, - flags: c_int, - addr: *const SOCKADDR, - addrlen: c_int, - ) -> c_int { - unsafe { c::sendto(socket, buf.cast::<u8>(), len, flags, addr, addrlen) } - } - pub unsafe fn getaddrinfo( - node: *const c_char, - service: *const c_char, - hints: *const ADDRINFOA, - res: *mut *mut ADDRINFOA, - ) -> c_int { - unsafe { c::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res) } - } -} - -pub struct Socket(OwnedSocket); - -static WSA_CLEANUP: OnceLock<unsafe extern "system" fn() -> i32> = OnceLock::new(); - -/// Checks whether the Windows socket interface has been started already, and -/// if not, starts it. -pub fn init() { - let _ = WSA_CLEANUP.get_or_init(|| unsafe { - let mut data: c::WSADATA = mem::zeroed(); - let ret = c::WSAStartup( - 0x202, // version 2.2 - &mut data, - ); - assert_eq!(ret, 0); - - // Only register `WSACleanup` if `WSAStartup` is actually ever called. - // Workaround to prevent linking to `WS2_32.dll` when no network functionality is used. - // See issue #85441. - c::WSACleanup - }); -} - -pub fn cleanup() { - // only perform cleanup if network functionality was actually initialized - if let Some(cleanup) = WSA_CLEANUP.get() { - unsafe { - cleanup(); - } - } -} - -/// Returns the last error from the Windows socket interface. -fn last_error() -> io::Error { - io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() }) -} - -#[doc(hidden)] -pub trait IsMinusOne { - fn is_minus_one(&self) -> bool; -} - -macro_rules! impl_is_minus_one { - ($($t:ident)*) => ($(impl IsMinusOne for $t { - fn is_minus_one(&self) -> bool { - *self == -1 - } - })*) -} - -impl_is_minus_one! { i8 i16 i32 i64 isize } - -/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1) -/// and if so, returns the last error from the Windows socket interface. This -/// function must be called before another call to the socket API is made. -pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> { - if t.is_minus_one() { Err(last_error()) } else { Ok(t) } -} - -/// A variant of `cvt` for `getaddrinfo` which return 0 for a success. -pub fn cvt_gai(err: c_int) -> io::Result<()> { - if err == 0 { Ok(()) } else { Err(last_error()) } -} - -/// Just to provide the same interface as sys/pal/unix/net.rs -pub fn cvt_r<T, F>(mut f: F) -> io::Result<T> -where - T: IsMinusOne, - F: FnMut() -> T, -{ - cvt(f()) -} - -impl Socket { - pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> { - let family = match *addr { - SocketAddr::V4(..) => netc::AF_INET, - SocketAddr::V6(..) => netc::AF_INET6, - }; - let socket = unsafe { - c::WSASocketW( - family, - ty, - 0, - ptr::null_mut(), - 0, - c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT, - ) - }; - - if socket != c::INVALID_SOCKET { - unsafe { Ok(Self::from_raw(socket)) } - } else { - let error = unsafe { c::WSAGetLastError() }; - - if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL { - return Err(io::Error::from_raw_os_error(error)); - } - - let socket = - unsafe { c::WSASocketW(family, ty, 0, ptr::null_mut(), 0, c::WSA_FLAG_OVERLAPPED) }; - - if socket == c::INVALID_SOCKET { - return Err(last_error()); - } - - unsafe { - let socket = Self::from_raw(socket); - socket.0.set_no_inherit()?; - Ok(socket) - } - } - } - - pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { - let (addr, len) = addr.into_inner(); - let result = unsafe { c::connect(self.as_raw(), addr.as_ptr(), len) }; - cvt(result).map(drop) - } - - pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { - self.set_nonblocking(true)?; - let result = self.connect(addr); - self.set_nonblocking(false)?; - - match result { - Err(ref error) if error.kind() == io::ErrorKind::WouldBlock => { - if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let mut timeout = c::TIMEVAL { - tv_sec: cmp::min(timeout.as_secs(), c_long::MAX as u64) as c_long, - tv_usec: timeout.subsec_micros() as c_long, - }; - - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - - let fds = { - let mut fds = unsafe { mem::zeroed::<c::FD_SET>() }; - fds.fd_count = 1; - fds.fd_array[0] = self.as_raw(); - fds - }; - - let mut writefds = fds; - let mut errorfds = fds; - - let count = { - let result = unsafe { - c::select(1, ptr::null_mut(), &mut writefds, &mut errorfds, &timeout) - }; - cvt(result)? - }; - - match count { - 0 => Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")), - _ => { - if writefds.fd_count != 1 { - if let Some(e) = self.take_error()? { - return Err(e); - } - } - - Ok(()) - } - } - } - _ => result, - } - } - - pub fn accept(&self, storage: *mut c::SOCKADDR, len: *mut c_int) -> io::Result<Socket> { - let socket = unsafe { c::accept(self.as_raw(), storage, len) }; - - match socket { - c::INVALID_SOCKET => Err(last_error()), - _ => unsafe { Ok(Self::from_raw(socket)) }, - } - } - - pub fn duplicate(&self) -> io::Result<Socket> { - Ok(Self(self.0.try_clone()?)) - } - - fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { - // On unix when a socket is shut down all further reads return 0, so we - // do the same on windows to map a shut down socket to returning EOF. - let length = cmp::min(buf.capacity(), i32::MAX as usize) as i32; - let result = - unsafe { c::recv(self.as_raw(), buf.as_mut().as_mut_ptr() as *mut _, length, flags) }; - - match result { - c::SOCKET_ERROR => { - let error = unsafe { c::WSAGetLastError() }; - - if error == c::WSAESHUTDOWN { - Ok(()) - } else { - Err(io::Error::from_raw_os_error(error)) - } - } - _ => { - unsafe { buf.advance_unchecked(result as usize) }; - Ok(()) - } - } - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), 0)?; - Ok(buf.len()) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.recv_with_flags(buf, 0) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - // On unix when a socket is shut down all further reads return 0, so we - // do the same on windows to map a shut down socket to returning EOF. - let length = cmp::min(bufs.len(), u32::MAX as usize) as u32; - let mut nread = 0; - let mut flags = 0; - let result = unsafe { - c::WSARecv( - self.as_raw(), - bufs.as_mut_ptr() as *mut c::WSABUF, - length, - &mut nread, - &mut flags, - ptr::null_mut(), - None, - ) - }; - - match result { - 0 => Ok(nread as usize), - _ => { - let error = unsafe { c::WSAGetLastError() }; - - if error == c::WSAESHUTDOWN { - Ok(0) - } else { - Err(io::Error::from_raw_os_error(error)) - } - } - } - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - true - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), c::MSG_PEEK)?; - Ok(buf.len()) - } - - fn recv_from_with_flags( - &self, - buf: &mut [u8], - flags: c_int, - ) -> io::Result<(usize, SocketAddr)> { - let mut storage = unsafe { mem::zeroed::<c::SOCKADDR_STORAGE>() }; - let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; - let length = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t; - - // On unix when a socket is shut down all further reads return 0, so we - // do the same on windows to map a shut down socket to returning EOF. - let result = unsafe { - c::recvfrom( - self.as_raw(), - buf.as_mut_ptr() as *mut _, - length, - flags, - (&raw mut storage) as *mut _, - &mut addrlen, - ) - }; - - match result { - c::SOCKET_ERROR => { - let error = unsafe { c::WSAGetLastError() }; - - if error == c::WSAESHUTDOWN { - Ok((0, net::sockaddr_to_addr(&storage, addrlen as usize)?)) - } else { - Err(io::Error::from_raw_os_error(error)) - } - } - _ => Ok((result as usize, net::sockaddr_to_addr(&storage, addrlen as usize)?)), - } - } - - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, 0) - } - - pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, c::MSG_PEEK) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let length = cmp::min(bufs.len(), u32::MAX as usize) as u32; - let mut nwritten = 0; - let result = unsafe { - c::WSASend( - self.as_raw(), - bufs.as_ptr() as *const c::WSABUF as *mut _, - length, - &mut nwritten, - 0, - ptr::null_mut(), - None, - ) - }; - cvt(result).map(|_| nwritten as usize) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - true - } - - pub fn set_timeout(&self, dur: Option<Duration>, kind: c_int) -> io::Result<()> { - let timeout = match dur { - Some(dur) => { - let timeout = sys::dur2timeout(dur); - if timeout == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - timeout - } - None => 0, - }; - net::setsockopt(self, c::SOL_SOCKET, kind, timeout) - } - - pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> { - let raw: u32 = net::getsockopt(self, c::SOL_SOCKET, kind)?; - if raw == 0 { - Ok(None) - } else { - let secs = raw / 1000; - let nsec = (raw % 1000) * 1000000; - Ok(Some(Duration::new(secs as u64, nsec as u32))) - } - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - let how = match how { - Shutdown::Write => c::SD_SEND, - Shutdown::Read => c::SD_RECEIVE, - Shutdown::Both => c::SD_BOTH, - }; - let result = unsafe { c::shutdown(self.as_raw(), how) }; - cvt(result).map(drop) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut nonblocking = nonblocking as c_ulong; - let result = - unsafe { c::ioctlsocket(self.as_raw(), c::FIONBIO as c_int, &mut nonblocking) }; - cvt(result).map(drop) - } - - pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { - let linger = c::LINGER { - l_onoff: linger.is_some() as c_ushort, - l_linger: linger.unwrap_or_default().as_secs() as c_ushort, - }; - - net::setsockopt(self, c::SOL_SOCKET, c::SO_LINGER, linger) - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - let val: c::LINGER = net::getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?; - - Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) - } - - pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { - net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BOOL) - } - - pub fn nodelay(&self) -> io::Result<bool> { - let raw: c::BOOL = net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?; - Ok(raw != 0) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - let raw: c_int = net::getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)?; - if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } - } - - // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> c::SOCKET { - debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>()); - debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>()); - self.as_inner().as_raw_socket() as c::SOCKET - } - pub unsafe fn from_raw(raw: c::SOCKET) -> Self { - debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>()); - debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>()); - unsafe { Self::from_raw_socket(raw as RawSocket) } - } -} - -#[unstable(reason = "not public", issue = "none", feature = "fd_read")] -impl<'a> Read for &'a Socket { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - (**self).read(buf) - } -} - -impl AsInner<OwnedSocket> for Socket { - #[inline] - fn as_inner(&self) -> &OwnedSocket { - &self.0 - } -} - -impl FromInner<OwnedSocket> for Socket { - fn from_inner(sock: OwnedSocket) -> Socket { - Socket(sock) - } -} - -impl IntoInner<OwnedSocket> for Socket { - fn into_inner(self) -> OwnedSocket { - self.0 - } -} - -impl AsSocket for Socket { - fn as_socket(&self) -> BorrowedSocket<'_> { - self.0.as_socket() - } -} - -impl AsRawSocket for Socket { - fn as_raw_socket(&self) -> RawSocket { - self.0.as_raw_socket() - } -} - -impl IntoRawSocket for Socket { - fn into_raw_socket(self) -> RawSocket { - self.0.into_raw_socket() - } -} - -impl FromRawSocket for Socket { - unsafe fn from_raw_socket(raw_socket: RawSocket) -> Self { - unsafe { Self(FromRawSocket::from_raw_socket(raw_socket)) } - } -} diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index a64cd068560..8ba2b6e2f20 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs @@ -7,7 +7,6 @@ pub mod env; pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; -pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys/pal/xous/net/dns.rs b/library/std/src/sys/pal/xous/net/dns.rs deleted file mode 100644 index ff6e49ed2d4..00000000000 --- a/library/std/src/sys/pal/xous/net/dns.rs +++ /dev/null @@ -1,128 +0,0 @@ -use core::convert::{TryFrom, TryInto}; - -use crate::io; -use crate::net::{Ipv4Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; -use crate::os::xous::ffi::lend_mut; -use crate::os::xous::services::{DnsLendMut, dns_server}; - -pub struct DnsError { - #[allow(dead_code)] - pub code: u8, -} - -#[repr(C, align(4096))] -struct LookupHostQuery([u8; 4096]); - -pub struct LookupHost { - data: LookupHostQuery, - port: u16, - offset: usize, - count: usize, -} - -impl LookupHost { - pub fn port(&self) -> u16 { - self.port - } -} - -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - if self.offset >= self.data.0.len() { - return None; - } - match self.data.0.get(self.offset) { - Some(&4) => { - self.offset += 1; - if self.offset + 4 > self.data.0.len() { - return None; - } - let result = Some(SocketAddr::V4(SocketAddrV4::new( - Ipv4Addr::new( - self.data.0[self.offset], - self.data.0[self.offset + 1], - self.data.0[self.offset + 2], - self.data.0[self.offset + 3], - ), - self.port, - ))); - self.offset += 4; - result - } - Some(&6) => { - self.offset += 1; - if self.offset + 16 > self.data.0.len() { - return None; - } - let mut new_addr = [0u8; 16]; - for (src, octet) in self.data.0[(self.offset + 1)..(self.offset + 16 + 1)] - .iter() - .zip(new_addr.iter_mut()) - { - *octet = *src; - } - let result = - Some(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.port, 0, 0))); - self.offset += 16; - result - } - _ => None, - } - } -} - -pub fn lookup(query: &str, port: u16) -> Result<LookupHost, DnsError> { - let mut result = LookupHost { data: LookupHostQuery([0u8; 4096]), offset: 0, count: 0, port }; - - // Copy the query into the message that gets sent to the DNS server - for (query_byte, result_byte) in query.as_bytes().iter().zip(result.data.0.iter_mut()) { - *result_byte = *query_byte; - } - - lend_mut( - dns_server(), - DnsLendMut::RawLookup.into(), - &mut result.data.0, - 0, - query.as_bytes().len(), - ) - .unwrap(); - if result.data.0[0] != 0 { - return Err(DnsError { code: result.data.0[1] }); - } - assert_eq!(result.offset, 0); - result.count = result.data.0[1] as usize; - - // Advance the offset to the first record - result.offset = 2; - Ok(result) -} - -impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(s: &str) -> io::Result<LookupHost> { - macro_rules! try_opt { - ($e:expr, $msg:expr) => { - match $e { - Some(r) => r, - None => return Err(io::const_error!(io::ErrorKind::InvalidInput, &$msg)), - } - }; - } - - // split the string by ':' and convert the second part to u16 - let (host, port_str) = try_opt!(s.rsplit_once(':'), "invalid socket address"); - let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); - (host, port).try_into() - } -} - -impl TryFrom<(&str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(v: (&str, u16)) -> io::Result<LookupHost> { - lookup(v.0, v.1).map_err(|_e| io::const_error!(io::ErrorKind::InvalidInput, &"DNS failure")) - } -} diff --git a/library/std/src/sys/pal/xous/net/mod.rs b/library/std/src/sys/pal/xous/net/mod.rs deleted file mode 100644 index 3e18ed24208..00000000000 --- a/library/std/src/sys/pal/xous/net/mod.rs +++ /dev/null @@ -1,83 +0,0 @@ -mod dns; - -mod tcpstream; -pub use tcpstream::*; - -mod tcplistener; -pub use tcplistener::*; - -mod udp; -pub use udp::*; - -// this structure needs to be synchronized with what's in net/src/api.rs -#[repr(C)] -#[derive(Debug)] -enum NetError { - // Ok = 0, - Unaddressable = 1, - SocketInUse = 2, - // AccessDenied = 3, - Invalid = 4, - // Finished = 5, - LibraryError = 6, - // AlreadyUsed = 7, - TimedOut = 8, - WouldBlock = 9, -} - -#[repr(C, align(4096))] -struct ConnectRequest { - raw: [u8; 4096], -} - -#[repr(C, align(4096))] -struct SendData { - raw: [u8; 4096], -} - -#[repr(C, align(4096))] -pub struct ReceiveData { - raw: [u8; 4096], -} - -#[repr(C, align(4096))] -pub struct GetAddress { - raw: [u8; 4096], -} - -pub use dns::LookupHost; - -#[allow(nonstandard_style)] -pub mod netc { - pub const AF_INET: u8 = 0; - pub const AF_INET6: u8 = 1; - pub type sa_family_t = u8; - - #[derive(Copy, Clone)] - pub struct in_addr { - pub s_addr: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in { - #[allow(dead_code)] - pub sin_family: sa_family_t, - pub sin_port: u16, - pub sin_addr: in_addr, - } - - #[derive(Copy, Clone)] - pub struct in6_addr { - pub s6_addr: [u8; 16], - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in6 { - #[allow(dead_code)] - pub sin6_family: sa_family_t, - pub sin6_port: u16, - pub sin6_addr: in6_addr, - pub sin6_flowinfo: u32, - pub sin6_scope_id: u32, - } -} diff --git a/library/std/src/sys/pal/xous/net/tcplistener.rs b/library/std/src/sys/pal/xous/net/tcplistener.rs deleted file mode 100644 index 640a02a64f5..00000000000 --- a/library/std/src/sys/pal/xous/net/tcplistener.rs +++ /dev/null @@ -1,243 +0,0 @@ -use core::convert::TryInto; -use core::sync::atomic::{AtomicBool, AtomicU16, AtomicUsize, Ordering}; - -use super::*; -use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; -use crate::os::xous::services; -use crate::sync::Arc; -use crate::{fmt, io}; - -macro_rules! unimpl { - () => { - return Err(io::const_error!( - io::ErrorKind::Unsupported, - &"This function is not yet implemented", - )); - }; -} - -#[derive(Clone)] -pub struct TcpListener { - fd: Arc<AtomicU16>, - local: SocketAddr, - handle_count: Arc<AtomicUsize>, - nonblocking: Arc<AtomicBool>, -} - -impl TcpListener { - pub fn bind(socketaddr: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - let mut addr = *socketaddr?; - - let fd = TcpListener::bind_inner(&mut addr)?; - return Ok(TcpListener { - fd: Arc::new(AtomicU16::new(fd)), - local: addr, - handle_count: Arc::new(AtomicUsize::new(1)), - nonblocking: Arc::new(AtomicBool::new(false)), - }); - } - - /// This returns the raw fd of a Listener, so that it can also be used by the - /// accept routine to replenish the Listener object after its handle has been converted into - /// a TcpStream object. - fn bind_inner(addr: &mut SocketAddr) -> io::Result<u16> { - // Construct the request - let mut connect_request = ConnectRequest { raw: [0u8; 4096] }; - - // Serialize the StdUdpBind structure. This is done "manually" because we don't want to - // make an auto-serdes (like bincode or rkyv) crate a dependency of Xous. - let port_bytes = addr.port().to_le_bytes(); - connect_request.raw[0] = port_bytes[0]; - connect_request.raw[1] = port_bytes[1]; - match addr.ip() { - IpAddr::V4(addr) => { - connect_request.raw[2] = 4; - for (dest, src) in connect_request.raw[3..].iter_mut().zip(addr.octets()) { - *dest = src; - } - } - IpAddr::V6(addr) => { - connect_request.raw[2] = 6; - for (dest, src) in connect_request.raw[3..].iter_mut().zip(addr.octets()) { - *dest = src; - } - } - } - - let Ok((_, valid)) = crate::os::xous::ffi::lend_mut( - services::net_server(), - services::NetLendMut::StdTcpListen.into(), - &mut connect_request.raw, - 0, - 4096, - ) else { - return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")); - }; - - // The first four bytes should be zero upon success, and will be nonzero - // for an error. - let response = connect_request.raw; - if response[0] != 0 || valid == 0 { - let errcode = response[1]; - if errcode == NetError::SocketInUse as u8 { - return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); - } else if errcode == NetError::Invalid as u8 { - return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address")); - } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); - } else { - return Err(io::const_error!( - io::ErrorKind::Other, - &"Unable to connect or internal error" - )); - } - } - let fd = response[1] as usize; - if addr.port() == 0 { - // oddly enough, this is a valid port and it means "give me something valid, up to you what that is" - let assigned_port = u16::from_le_bytes(response[2..4].try_into().unwrap()); - addr.set_port(assigned_port); - } - // println!("TcpListening with file handle of {}\r\n", fd); - Ok(fd.try_into().unwrap()) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - Ok(self.local) - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - let mut receive_request = ReceiveData { raw: [0u8; 4096] }; - - if self.nonblocking.load(Ordering::Relaxed) { - // nonblocking - receive_request.raw[0] = 0; - } else { - // blocking - receive_request.raw[0] = 1; - } - - if let Ok((_offset, _valid)) = crate::os::xous::ffi::lend_mut( - services::net_server(), - services::NetLendMut::StdTcpAccept(self.fd.load(Ordering::Relaxed)).into(), - &mut receive_request.raw, - 0, - 0, - ) { - if receive_request.raw[0] != 0 { - // error case - if receive_request.raw[1] == NetError::TimedOut as u8 { - return Err(io::const_error!(io::ErrorKind::TimedOut, &"accept timed out",)); - } else if receive_request.raw[1] == NetError::WouldBlock as u8 { - return Err( - io::const_error!(io::ErrorKind::WouldBlock, &"accept would block",), - ); - } else if receive_request.raw[1] == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); - } else { - return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); - } - } else { - // accept successful - let rr = &receive_request.raw; - let stream_fd = u16::from_le_bytes(rr[1..3].try_into().unwrap()); - let port = u16::from_le_bytes(rr[20..22].try_into().unwrap()); - let addr = if rr[3] == 4 { - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(rr[4], rr[5], rr[6], rr[7])), port) - } else if rr[3] == 6 { - SocketAddr::new( - IpAddr::V6(Ipv6Addr::new( - u16::from_be_bytes(rr[4..6].try_into().unwrap()), - u16::from_be_bytes(rr[6..8].try_into().unwrap()), - u16::from_be_bytes(rr[8..10].try_into().unwrap()), - u16::from_be_bytes(rr[10..12].try_into().unwrap()), - u16::from_be_bytes(rr[12..14].try_into().unwrap()), - u16::from_be_bytes(rr[14..16].try_into().unwrap()), - u16::from_be_bytes(rr[16..18].try_into().unwrap()), - u16::from_be_bytes(rr[18..20].try_into().unwrap()), - )), - port, - ) - } else { - return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); - }; - - // replenish the listener - let mut local_copy = self.local.clone(); // port is non-0 by this time, but the method signature needs a mut - let new_fd = TcpListener::bind_inner(&mut local_copy)?; - self.fd.store(new_fd, Ordering::Relaxed); - - // now return a stream converted from the old stream's fd - Ok((TcpStream::from_listener(stream_fd, self.local.port(), port, addr), addr)) - } - } else { - Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to accept")) - } - } - - pub fn duplicate(&self) -> io::Result<TcpListener> { - self.handle_count.fetch_add(1, Ordering::Relaxed); - Ok(self.clone()) - } - - pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { - if ttl > 255 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "TTL must be less than 256")); - } - crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdSetTtlTcp(self.fd.load(Ordering::Relaxed), ttl).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|_| ()) - } - - pub fn ttl(&self) -> io::Result<u32> { - Ok(crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdGetTtlTcp(self.fd.load(Ordering::Relaxed)).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|res| res[0] as _)?) - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn only_v6(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - // this call doesn't have a meaning on our platform, but we can at least not panic if it's used. - Ok(None) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - self.nonblocking.store(nonblocking, Ordering::Relaxed); - Ok(()) - } -} - -impl fmt::Debug for TcpListener { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "TCP listening on {:?}", self.local) - } -} - -impl Drop for TcpListener { - fn drop(&mut self) { - if self.handle_count.fetch_sub(1, Ordering::Relaxed) == 1 { - // only drop if we're the last clone - crate::os::xous::ffi::blocking_scalar( - services::net_server(), - crate::os::xous::services::NetBlockingScalar::StdTcpClose( - self.fd.load(Ordering::Relaxed), - ) - .into(), - ) - .unwrap(); - } - } -} diff --git a/library/std/src/sys/pal/xous/net/tcpstream.rs b/library/std/src/sys/pal/xous/net/tcpstream.rs deleted file mode 100644 index 572dd6b3b63..00000000000 --- a/library/std/src/sys/pal/xous/net/tcpstream.rs +++ /dev/null @@ -1,424 +0,0 @@ -use core::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering}; - -use super::*; -use crate::fmt; -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{IpAddr, Ipv4Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6}; -use crate::os::xous::services; -use crate::sync::Arc; -use crate::time::Duration; - -macro_rules! unimpl { - () => { - return Err(io::const_error!( - io::ErrorKind::Unsupported, - &"This function is not yet implemented", - )); - }; -} - -enum ReadOrPeek { - Read, - Peek, -} - -#[derive(Clone)] -pub struct TcpStream { - fd: u16, - local_port: u16, - remote_port: u16, - peer_addr: SocketAddr, - // milliseconds - read_timeout: Arc<AtomicU32>, - // milliseconds - write_timeout: Arc<AtomicU32>, - handle_count: Arc<AtomicUsize>, - nonblocking: Arc<AtomicBool>, -} - -fn sockaddr_to_buf(duration: Duration, addr: &SocketAddr, buf: &mut [u8]) { - // Construct the request. - let port_bytes = addr.port().to_le_bytes(); - buf[0] = port_bytes[0]; - buf[1] = port_bytes[1]; - for (dest, src) in buf[2..].iter_mut().zip((duration.as_millis() as u64).to_le_bytes()) { - *dest = src; - } - match addr.ip() { - IpAddr::V4(addr) => { - buf[10] = 4; - for (dest, src) in buf[11..].iter_mut().zip(addr.octets()) { - *dest = src; - } - } - IpAddr::V6(addr) => { - buf[10] = 6; - for (dest, src) in buf[11..].iter_mut().zip(addr.octets()) { - *dest = src; - } - } - } -} - -impl TcpStream { - pub(crate) fn from_listener( - fd: u16, - local_port: u16, - remote_port: u16, - peer_addr: SocketAddr, - ) -> TcpStream { - TcpStream { - fd, - local_port, - remote_port, - peer_addr, - read_timeout: Arc::new(AtomicU32::new(0)), - write_timeout: Arc::new(AtomicU32::new(0)), - handle_count: Arc::new(AtomicUsize::new(1)), - nonblocking: Arc::new(AtomicBool::new(false)), - } - } - - pub fn connect(socketaddr: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - Self::connect_timeout(socketaddr?, Duration::ZERO) - } - - pub fn connect_timeout(addr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> { - let mut connect_request = ConnectRequest { raw: [0u8; 4096] }; - - // Construct the request. - sockaddr_to_buf(duration, &addr, &mut connect_request.raw); - - let Ok((_, valid)) = crate::os::xous::ffi::lend_mut( - services::net_server(), - services::NetLendMut::StdTcpConnect.into(), - &mut connect_request.raw, - 0, - 4096, - ) else { - return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")); - }; - - // The first four bytes should be zero upon success, and will be nonzero - // for an error. - let response = connect_request.raw; - if response[0] != 0 || valid == 0 { - // errcode is a u8 but stuck in a u16 where the upper byte is invalid. Mask & decode accordingly. - let errcode = response[0]; - if errcode == NetError::SocketInUse as u8 { - return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use",)); - } else if errcode == NetError::Unaddressable as u8 { - return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address",)); - } else { - return Err(io::const_error!( - io::ErrorKind::InvalidInput, - &"Unable to connect or internal error", - )); - } - } - let fd = u16::from_le_bytes([response[2], response[3]]); - let local_port = u16::from_le_bytes([response[4], response[5]]); - let remote_port = u16::from_le_bytes([response[6], response[7]]); - // println!( - // "Connected with local port of {}, remote port of {}, file handle of {}", - // local_port, remote_port, fd - // ); - Ok(TcpStream { - fd, - local_port, - remote_port, - peer_addr: *addr, - read_timeout: Arc::new(AtomicU32::new(0)), - write_timeout: Arc::new(AtomicU32::new(0)), - handle_count: Arc::new(AtomicUsize::new(1)), - nonblocking: Arc::new(AtomicBool::new(false)), - }) - } - - pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> { - if let Some(to) = timeout { - if to.is_zero() { - return Err(io::Error::ZERO_TIMEOUT); - } - } - self.read_timeout.store( - timeout.map(|t| t.as_millis().min(u32::MAX as u128) as u32).unwrap_or_default(), - Ordering::Relaxed, - ); - Ok(()) - } - - pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> { - if let Some(to) = timeout { - if to.is_zero() { - return Err(io::Error::ZERO_TIMEOUT); - } - } - self.write_timeout.store( - timeout.map(|t| t.as_millis().min(u32::MAX as u128) as u32).unwrap_or_default(), - Ordering::Relaxed, - ); - Ok(()) - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - match self.read_timeout.load(Ordering::Relaxed) { - 0 => Ok(None), - t => Ok(Some(Duration::from_millis(t as u64))), - } - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - match self.write_timeout.load(Ordering::Relaxed) { - 0 => Ok(None), - t => Ok(Some(Duration::from_millis(t as u64))), - } - } - - fn read_or_peek(&self, buf: &mut [u8], op: ReadOrPeek) -> io::Result<usize> { - let mut receive_request = ReceiveData { raw: [0u8; 4096] }; - let data_to_read = buf.len().min(receive_request.raw.len()); - - let opcode = match op { - ReadOrPeek::Read => { - services::NetLendMut::StdTcpRx(self.fd, self.nonblocking.load(Ordering::Relaxed)) - } - ReadOrPeek::Peek => { - services::NetLendMut::StdTcpPeek(self.fd, self.nonblocking.load(Ordering::Relaxed)) - } - }; - - let Ok((offset, length)) = crate::os::xous::ffi::lend_mut( - services::net_server(), - opcode.into(), - &mut receive_request.raw, - // Reuse the `offset` as the read timeout - self.read_timeout.load(Ordering::Relaxed) as usize, - data_to_read, - ) else { - return Err(io::const_error!( - io::ErrorKind::InvalidInput, - &"Library failure: wrong message type or messaging error" - )); - }; - - if offset != 0 { - for (dest, src) in buf.iter_mut().zip(receive_request.raw[..length].iter()) { - *dest = *src; - } - Ok(length) - } else { - let result = receive_request.raw; - if result[0] != 0 { - if result[1] == 8 { - // timed out - return Err(io::const_error!(io::ErrorKind::TimedOut, &"Timeout",)); - } - if result[1] == 9 { - // would block - return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",)); - } - } - Err(io::const_error!(io::ErrorKind::Other, &"recv_slice failure")) - } - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - self.read_or_peek(buf, ReadOrPeek::Peek) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - self.read_or_peek(buf, ReadOrPeek::Read) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - crate::io::default_read_vectored(|b| self.read(b), bufs) - } - - pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { - crate::io::default_read_buf(|buf| self.read(buf), cursor) - } - - pub fn is_read_vectored(&self) -> bool { - false - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - let mut send_request = SendData { raw: [0u8; 4096] }; - for (dest, src) in send_request.raw.iter_mut().zip(buf) { - *dest = *src; - } - let buf_len = send_request.raw.len().min(buf.len()); - - let (_offset, _valid) = crate::os::xous::ffi::lend_mut( - services::net_server(), - services::NetLendMut::StdTcpTx(self.fd).into(), - &mut send_request.raw, - // Reuse the offset as the timeout - self.write_timeout.load(Ordering::Relaxed) as usize, - buf_len, - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")))?; - - if send_request.raw[0] != 0 { - if send_request.raw[4] == 8 { - // timed out - return Err(io::const_error!( - io::ErrorKind::BrokenPipe, - &"Timeout or connection closed", - )); - } else if send_request.raw[4] == 9 { - // would block - return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",)); - } else { - return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Error when sending",)); - } - } - Ok(u32::from_le_bytes([ - send_request.raw[4], - send_request.raw[5], - send_request.raw[6], - send_request.raw[7], - ]) as usize) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - crate::io::default_write_vectored(|b| self.write(b), bufs) - } - - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - Ok(self.peer_addr) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - let mut get_addr = GetAddress { raw: [0u8; 4096] }; - - let Ok((_offset, _valid)) = crate::os::xous::ffi::lend_mut( - services::net_server(), - services::NetLendMut::StdGetAddress(self.fd).into(), - &mut get_addr.raw, - 0, - 0, - ) else { - return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")); - }; - let mut i = get_addr.raw.iter(); - match *i.next().unwrap() { - 4 => Ok(SocketAddr::V4(SocketAddrV4::new( - Ipv4Addr::new( - *i.next().unwrap(), - *i.next().unwrap(), - *i.next().unwrap(), - *i.next().unwrap(), - ), - self.local_port, - ))), - 6 => { - let mut new_addr = [0u8; 16]; - for (src, octet) in i.zip(new_addr.iter_mut()) { - *octet = *src; - } - Ok(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.local_port, 0, 0))) - } - _ => Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")), - } - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdTcpStreamShutdown(self.fd, how).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|_| ()) - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - self.handle_count.fetch_add(1, Ordering::Relaxed); - Ok(self.clone()) - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn set_nodelay(&self, enabled: bool) -> io::Result<()> { - crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdSetNodelay(self.fd, enabled).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|_| ()) - } - - pub fn nodelay(&self) -> io::Result<bool> { - Ok(crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdGetNodelay(self.fd).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|res| res[0] != 0)?) - } - - pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { - if ttl > 255 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "TTL must be less than 256")); - } - crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdSetTtlTcp(self.fd, ttl).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|_| ()) - } - - pub fn ttl(&self) -> io::Result<u32> { - Ok(crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdGetTtlTcp(self.fd).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|res| res[0] as _)?) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - // this call doesn't have a meaning on our platform, but we can at least not panic if it's used. - Ok(None) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - self.nonblocking.store(nonblocking, Ordering::Relaxed); - Ok(()) - } -} - -impl fmt::Debug for TcpStream { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "TCP connection to {:?} port {} to local port {}", - self.peer_addr, self.remote_port, self.local_port - ) - } -} - -impl Drop for TcpStream { - fn drop(&mut self) { - if self.handle_count.fetch_sub(1, Ordering::Relaxed) == 1 { - // only drop if we're the last clone - crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdTcpClose(self.fd).into(), - ) - .unwrap(); - } - } -} diff --git a/library/std/src/sys/pal/xous/net/udp.rs b/library/std/src/sys/pal/xous/net/udp.rs deleted file mode 100644 index 1b7ecac6d3a..00000000000 --- a/library/std/src/sys/pal/xous/net/udp.rs +++ /dev/null @@ -1,459 +0,0 @@ -use core::convert::TryInto; -use core::sync::atomic::{AtomicUsize, Ordering}; - -use super::*; -use crate::cell::Cell; -use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; -use crate::os::xous::services; -use crate::sync::Arc; -use crate::time::Duration; -use crate::{fmt, io}; - -macro_rules! unimpl { - () => { - return Err(io::const_error!( - io::ErrorKind::Unsupported, - &"This function is not yet implemented", - )); - }; -} - -#[derive(Clone)] -pub struct UdpSocket { - fd: u16, - local: SocketAddr, - remote: Cell<Option<SocketAddr>>, - // in milliseconds. The setting applies only to `recv` calls after the timeout is set. - read_timeout: Cell<u64>, - // in milliseconds. The setting applies only to `send` calls after the timeout is set. - write_timeout: Cell<u64>, - handle_count: Arc<AtomicUsize>, - nonblocking: Cell<bool>, -} - -impl UdpSocket { - pub fn bind(socketaddr: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - let addr = socketaddr?; - // Construct the request - let mut connect_request = ConnectRequest { raw: [0u8; 4096] }; - - // Serialize the StdUdpBind structure. This is done "manually" because we don't want to - // make an auto-serdes (like bincode or rkyv) crate a dependency of Xous. - let port_bytes = addr.port().to_le_bytes(); - connect_request.raw[0] = port_bytes[0]; - connect_request.raw[1] = port_bytes[1]; - match addr.ip() { - IpAddr::V4(addr) => { - connect_request.raw[2] = 4; - for (dest, src) in connect_request.raw[3..].iter_mut().zip(addr.octets()) { - *dest = src; - } - } - IpAddr::V6(addr) => { - connect_request.raw[2] = 6; - for (dest, src) in connect_request.raw[3..].iter_mut().zip(addr.octets()) { - *dest = src; - } - } - } - - let response = crate::os::xous::ffi::lend_mut( - services::net_server(), - services::NetLendMut::StdUdpBind.into(), - &mut connect_request.raw, - 0, - 4096, - ); - - if let Ok((_, valid)) = response { - // The first four bytes should be zero upon success, and will be nonzero - // for an error. - let response = connect_request.raw; - if response[0] != 0 || valid == 0 { - let errcode = response[1]; - if errcode == NetError::SocketInUse as u8 { - return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); - } else if errcode == NetError::Invalid as u8 { - return Err(io::const_error!( - io::ErrorKind::InvalidInput, - &"Port can't be 0 or invalid address" - )); - } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); - } else { - return Err(io::const_error!( - io::ErrorKind::Other, - &"Unable to connect or internal error" - )); - } - } - let fd = response[1] as u16; - return Ok(UdpSocket { - fd, - local: *addr, - remote: Cell::new(None), - read_timeout: Cell::new(0), - write_timeout: Cell::new(0), - handle_count: Arc::new(AtomicUsize::new(1)), - nonblocking: Cell::new(false), - }); - } - Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")) - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - match self.remote.get() { - Some(dest) => Ok(dest), - None => Err(io::const_error!(io::ErrorKind::NotConnected, &"No peer specified")), - } - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - Ok(self.local) - } - - fn recv_inner(&self, buf: &mut [u8], do_peek: bool) -> io::Result<(usize, SocketAddr)> { - let mut receive_request = ReceiveData { raw: [0u8; 4096] }; - - if self.nonblocking.get() { - // nonblocking - receive_request.raw[0] = 0; - } else { - // blocking - receive_request.raw[0] = 1; - for (&s, d) in self - .read_timeout - .get() - .to_le_bytes() - .iter() - .zip(receive_request.raw[1..9].iter_mut()) - { - *d = s; - } - } - if let Ok((_offset, _valid)) = crate::os::xous::ffi::lend_mut( - services::net_server(), - services::NetLendMut::StdUdpRx(self.fd).into(), - &mut receive_request.raw, - if do_peek { 1 } else { 0 }, - 0, - ) { - if receive_request.raw[0] != 0 { - // error case - if receive_request.raw[1] == NetError::TimedOut as u8 { - return Err(io::const_error!(io::ErrorKind::TimedOut, &"recv timed out",)); - } else if receive_request.raw[1] == NetError::WouldBlock as u8 { - return Err(io::const_error!(io::ErrorKind::WouldBlock, &"recv would block",)); - } else if receive_request.raw[1] == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); - } else { - return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); - } - } else { - let rr = &receive_request.raw; - let rxlen = u16::from_le_bytes(rr[1..3].try_into().unwrap()); - let port = u16::from_le_bytes(rr[20..22].try_into().unwrap()); - let addr = if rr[3] == 4 { - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(rr[4], rr[5], rr[6], rr[7])), port) - } else if rr[3] == 6 { - SocketAddr::new( - IpAddr::V6(Ipv6Addr::new( - u16::from_be_bytes(rr[4..6].try_into().unwrap()), - u16::from_be_bytes(rr[6..8].try_into().unwrap()), - u16::from_be_bytes(rr[8..10].try_into().unwrap()), - u16::from_be_bytes(rr[10..12].try_into().unwrap()), - u16::from_be_bytes(rr[12..14].try_into().unwrap()), - u16::from_be_bytes(rr[14..16].try_into().unwrap()), - u16::from_be_bytes(rr[16..18].try_into().unwrap()), - u16::from_be_bytes(rr[18..20].try_into().unwrap()), - )), - port, - ) - } else { - return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); - }; - for (&s, d) in rr[22..22 + rxlen as usize].iter().zip(buf.iter_mut()) { - *d = s; - } - Ok((rxlen as usize, addr)) - } - } else { - Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to recv")) - } - } - - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_inner(buf, false) - } - - pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> { - self.recv_from(buf).map(|(len, _addr)| len) - } - - pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_inner(buf, true) - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - self.peek_from(buf).map(|(len, _addr)| len) - } - - pub fn connect(&self, maybe_addr: io::Result<&SocketAddr>) -> io::Result<()> { - let addr = maybe_addr?; - self.remote.set(Some(*addr)); - Ok(()) - } - - pub fn send(&self, buf: &[u8]) -> io::Result<usize> { - if let Some(addr) = self.remote.get() { - self.send_to(buf, &addr) - } else { - Err(io::const_error!(io::ErrorKind::NotConnected, &"No remote specified")) - } - } - - pub fn send_to(&self, buf: &[u8], addr: &SocketAddr) -> io::Result<usize> { - let mut tx_req = SendData { raw: [0u8; 4096] }; - - // Construct the request. - let port_bytes = addr.port().to_le_bytes(); - tx_req.raw[0] = port_bytes[0]; - tx_req.raw[1] = port_bytes[1]; - match addr.ip() { - IpAddr::V4(addr) => { - tx_req.raw[2] = 4; - for (dest, src) in tx_req.raw[3..].iter_mut().zip(addr.octets()) { - *dest = src; - } - } - IpAddr::V6(addr) => { - tx_req.raw[2] = 6; - for (dest, src) in tx_req.raw[3..].iter_mut().zip(addr.octets()) { - *dest = src; - } - } - } - let len = buf.len() as u16; - let len_bytes = len.to_le_bytes(); - tx_req.raw[19] = len_bytes[0]; - tx_req.raw[20] = len_bytes[1]; - for (&s, d) in buf.iter().zip(tx_req.raw[21..].iter_mut()) { - *d = s; - } - - // let buf = unsafe { - // xous::MemoryRange::new( - // &mut tx_req as *mut SendData as usize, - // core::mem::size_of::<SendData>(), - // ) - // .unwrap() - // }; - - // write time-outs are implemented on the caller side. Basically, if the Net crate server - // is too busy to take the call immediately: retry, until the timeout is reached. - let now = crate::time::Instant::now(); - let write_timeout = if self.nonblocking.get() { - // nonblocking - core::time::Duration::ZERO - } else { - // blocking - if self.write_timeout.get() == 0 { - // forever - core::time::Duration::from_millis(u64::MAX) - } else { - // or this amount of time - core::time::Duration::from_millis(self.write_timeout.get()) - } - }; - loop { - let response = crate::os::xous::ffi::try_lend_mut( - services::net_server(), - services::NetLendMut::StdUdpTx(self.fd).into(), - &mut tx_req.raw, - 0, - 4096, - ); - match response { - Ok((_, valid)) => { - let response = &tx_req.raw; - if response[0] != 0 || valid == 0 { - let errcode = response[1]; - if errcode == NetError::SocketInUse as u8 { - return Err(io::const_error!( - io::ErrorKind::ResourceBusy, - &"Socket in use" - )); - } else if errcode == NetError::Invalid as u8 { - return Err(io::const_error!( - io::ErrorKind::InvalidInput, - &"Socket not valid" - )); - } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); - } else { - return Err(io::const_error!( - io::ErrorKind::Other, - &"Unable to connect" - )); - } - } else { - // no error - return Ok(len as usize); - } - } - Err(crate::os::xous::ffi::Error::ServerQueueFull) => { - if now.elapsed() >= write_timeout { - return Err(io::const_error!( - io::ErrorKind::WouldBlock, - &"Write timed out" - )); - } else { - // question: do we want to do something a bit more gentle than immediately retrying? - crate::thread::yield_now(); - } - } - _ => return Err(io::const_error!(io::ErrorKind::Other, &"Library error")), - } - } - } - - pub fn duplicate(&self) -> io::Result<UdpSocket> { - self.handle_count.fetch_add(1, Ordering::Relaxed); - Ok(self.clone()) - } - - pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> { - if let Some(d) = timeout { - if d.is_zero() { - return Err(io::Error::ZERO_TIMEOUT); - } - } - self.read_timeout - .set(timeout.map(|t| t.as_millis().min(u64::MAX as u128) as u64).unwrap_or_default()); - Ok(()) - } - - pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> { - if let Some(d) = timeout { - if d.is_zero() { - return Err(io::Error::ZERO_TIMEOUT); - } - } - self.write_timeout - .set(timeout.map(|t| t.as_millis().min(u64::MAX as u128) as u64).unwrap_or_default()); - Ok(()) - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - match self.read_timeout.get() { - 0 => Ok(None), - t => Ok(Some(Duration::from_millis(t as u64))), - } - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - match self.write_timeout.get() { - 0 => Ok(None), - t => Ok(Some(Duration::from_millis(t as u64))), - } - } - - pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { - if ttl > 255 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "TTL must be less than 256")); - } - crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdSetTtlUdp(self.fd, ttl).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|_| ()) - } - - pub fn ttl(&self) -> io::Result<u32> { - Ok(crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdGetTtlUdp(self.fd).into(), - ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) - .map(|res| res[0] as _)?) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - // this call doesn't have a meaning on our platform, but we can at least not panic if it's used. - Ok(None) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - self.nonblocking.set(nonblocking); - Ok(()) - } - - // ------------- smoltcp base stack does not have multicast or broadcast support --------------- - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn broadcast(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unimpl!(); - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unimpl!(); - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unimpl!(); - } -} - -impl fmt::Debug for UdpSocket { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "UDP listening on {:?} to {:?}", self.local, self.remote.get(),) - } -} - -impl Drop for UdpSocket { - fn drop(&mut self) { - if self.handle_count.fetch_sub(1, Ordering::Relaxed) == 1 { - // only drop if we're the last clone - crate::os::xous::ffi::blocking_scalar( - services::net_server(), - services::NetBlockingScalar::StdUdpClose(self.fd).into(), - ) - .unwrap(); - } - } -} diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 6ea05772029..9e9ae861070 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -18,8 +18,6 @@ pub mod env; pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; -#[path = "../unsupported/net.rs"] -pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; |
