From 2579c7b98410a2df306c9289d30cc20849a9174c Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Sat, 14 Jan 2023 14:28:41 +0100 Subject: [PATCH] Add support for QNX Neutrino --- Cargo.toml | 2 +- src/lib.rs | 20 ++++++++++++++++---- src/sockaddr.rs | 1 + src/socket.rs | 12 +++++++++++- src/sys/unix.rs | 42 ++++++++++++++++++++++++++++++------------ 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dda00564..d59569b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ rustdoc-args = ["--cfg", "docsrs"] features = ["all"] [target."cfg(unix)".dependencies] -libc = "0.2.124" +libc = "0.2.139" [target.'cfg(windows)'.dependencies.windows-sys] version = "0.36" diff --git a/src/lib.rs b/src/lib.rs index a3963267..0b08a0f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -390,13 +390,19 @@ impl<'a> DerefMut for MaybeUninitSlice<'a> { pub struct TcpKeepalive { #[cfg_attr(target_os = "openbsd", allow(dead_code))] time: Option, - #[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "solaris")))] + #[cfg(not(any( + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "nto", + )))] interval: Option, #[cfg(not(any( target_os = "openbsd", target_os = "redox", target_os = "solaris", - target_os = "windows" + target_os = "windows", + target_os = "nto", )))] retries: Option, } @@ -406,13 +412,19 @@ impl TcpKeepalive { pub const fn new() -> TcpKeepalive { TcpKeepalive { time: None, - #[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "solaris")))] + #[cfg(not(any( + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "nto", + )))] interval: None, #[cfg(not(any( target_os = "openbsd", target_os = "redox", target_os = "solaris", - target_os = "windows" + target_os = "windows", + target_os = "nto", )))] retries: None, } diff --git a/src/sockaddr.rs b/src/sockaddr.rs index 1a19b5ac..2de65054 100644 --- a/src/sockaddr.rs +++ b/src/sockaddr.rs @@ -305,6 +305,7 @@ impl fmt::Debug for SockAddr { target_os = "netbsd", target_os = "openbsd", target_os = "vxworks", + target_os = "nto", ))] f.field("ss_len", &self.storage.ss_len); f.field("ss_family", &self.storage.ss_family) diff --git a/src/socket.rs b/src/socket.rs index afa8a08f..baedc769 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -11,7 +11,9 @@ use std::io::{self, Read, Write}; #[cfg(not(target_os = "redox"))] use std::io::{IoSlice, IoSliceMut}; use std::mem::MaybeUninit; -use std::net::{self, Ipv4Addr, Ipv6Addr, Shutdown}; +#[cfg(not(target_os = "nto"))] +use std::net::Ipv6Addr; +use std::net::{self, Ipv4Addr, Shutdown}; #[cfg(unix)] use std::os::unix::io::{FromRawFd, IntoRawFd}; #[cfg(windows)] @@ -1174,6 +1176,7 @@ impl Socket { target_os = "openbsd", target_os = "redox", target_os = "solaris", + target_os = "nto", )))] pub fn join_multicast_v4_n( &self, @@ -1203,6 +1206,7 @@ impl Socket { target_os = "openbsd", target_os = "redox", target_os = "solaris", + target_os = "nto", )))] pub fn leave_multicast_v4_n( &self, @@ -1234,6 +1238,7 @@ impl Socket { target_os = "openbsd", target_os = "redox", target_os = "fuchsia", + target_os = "nto", )))] pub fn join_ssm_v4( &self, @@ -1268,6 +1273,7 @@ impl Socket { target_os = "openbsd", target_os = "redox", target_os = "fuchsia", + target_os = "nto", )))] pub fn leave_ssm_v4( &self, @@ -1443,6 +1449,7 @@ impl Socket { target_os = "redox", target_os = "solaris", target_os = "haiku", + target_os = "nto", )))] pub fn set_recv_tos(&self, recv_tos: bool) -> io::Result<()> { unsafe { @@ -1469,6 +1476,7 @@ impl Socket { target_os = "redox", target_os = "solaris", target_os = "haiku", + target_os = "nto", )))] pub fn recv_tos(&self) -> io::Result { unsafe { @@ -1491,6 +1499,7 @@ impl Socket { /// This function specifies a new multicast group for this socket to join. /// The address must be a valid multicast address, and `interface` is the /// index of the interface to join/leave (or 0 to indicate any interface). + #[cfg(not(target_os = "nto"))] pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> { let mreq = sys::Ipv6Mreq { ipv6mr_multiaddr: sys::to_in6_addr(multiaddr), @@ -1514,6 +1523,7 @@ impl Socket { /// For more information about this option, see [`join_multicast_v6`]. /// /// [`join_multicast_v6`]: Socket::join_multicast_v6 + #[cfg(not(target_os = "nto"))] pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> { let mreq = sys::Ipv6Mreq { ipv6mr_multiaddr: sys::to_in6_addr(multiaddr), diff --git a/src/sys/unix.rs b/src/sys/unix.rs index fe9ba3b0..3adef88d 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -76,6 +76,8 @@ pub(crate) use libc::{ #[cfg(not(target_os = "redox"))] pub(crate) use libc::{MSG_TRUNC, SO_OOBINLINE}; // Used in `Socket`. +#[cfg(not(target_os = "nto"))] +pub(crate) use libc::ipv6_mreq as Ipv6Mreq; #[cfg(not(any( target_os = "dragonfly", target_os = "fuchsia", @@ -98,6 +100,7 @@ pub(crate) use libc::IP_HDRINCL; target_os = "redox", target_os = "solaris", target_os = "haiku", + target_os = "nto", )))] pub(crate) use libc::IP_RECVTOS; #[cfg(not(any( @@ -112,11 +115,11 @@ pub(crate) use libc::SO_LINGER; #[cfg(target_vendor = "apple")] pub(crate) use libc::SO_LINGER_SEC as SO_LINGER; pub(crate) use libc::{ - ip_mreq as IpMreq, ipv6_mreq as Ipv6Mreq, linger, IPPROTO_IP, IPPROTO_IPV6, - IPV6_MULTICAST_HOPS, IPV6_MULTICAST_IF, IPV6_MULTICAST_LOOP, IPV6_UNICAST_HOPS, IPV6_V6ONLY, - IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_IF, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, - IP_TTL, MSG_OOB, MSG_PEEK, SOL_SOCKET, SO_BROADCAST, SO_ERROR, SO_KEEPALIVE, SO_RCVBUF, - SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO, SO_TYPE, TCP_NODELAY, + ip_mreq as IpMreq, linger, IPPROTO_IP, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_IF, + IPV6_MULTICAST_LOOP, IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, + IP_MULTICAST_IF, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_TTL, MSG_OOB, MSG_PEEK, SOL_SOCKET, + SO_BROADCAST, SO_ERROR, SO_KEEPALIVE, SO_RCVBUF, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, + SO_SNDTIMEO, SO_TYPE, TCP_NODELAY, }; #[cfg(not(any( target_os = "dragonfly", @@ -125,6 +128,7 @@ pub(crate) use libc::{ target_os = "openbsd", target_os = "redox", target_os = "fuchsia", + target_os = "nto", )))] pub(crate) use libc::{ ip_mreq_source as IpMreqSource, IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, @@ -137,6 +141,7 @@ pub(crate) use libc::{ target_os = "netbsd", target_os = "openbsd", target_os = "solaris", + target_os = "nto", target_vendor = "apple" )))] pub(crate) use libc::{IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP}; @@ -171,9 +176,14 @@ pub(crate) use libc::{TCP_KEEPCNT, TCP_KEEPINTVL}; // See this type in the Windows file. pub(crate) type Bool = c_int; -#[cfg(target_vendor = "apple")] +#[cfg(any(target_vendor = "apple", target_os = "nto"))] use libc::TCP_KEEPALIVE as KEEPALIVE_TIME; -#[cfg(not(any(target_vendor = "apple", target_os = "haiku", target_os = "openbsd")))] +#[cfg(not(any( + target_vendor = "apple", + target_os = "haiku", + target_os = "openbsd", + target_os = "nto", +)))] use libc::TCP_KEEPIDLE as KEEPALIVE_TIME; /// Helper macro to execute a system call that returns an `io::Result`. @@ -236,6 +246,7 @@ type IovLen = usize; target_os = "netbsd", target_os = "openbsd", target_os = "solaris", + target_os = "nto", target_vendor = "apple", ))] type IovLen = c_int; @@ -902,7 +913,7 @@ pub(crate) fn keepalive_time(fd: Socket) -> io::Result { #[allow(unused_variables)] pub(crate) fn set_tcp_keepalive(fd: Socket, keepalive: &TcpKeepalive) -> io::Result<()> { - #[cfg(not(any(target_os = "haiku", target_os = "openbsd")))] + #[cfg(not(any(target_os = "haiku", target_os = "openbsd", target_os = "nto")))] if let Some(time) = keepalive.time { let secs = into_secs(time); unsafe { setsockopt(fd, libc::IPPROTO_TCP, KEEPALIVE_TIME, secs)? } @@ -929,10 +940,16 @@ pub(crate) fn set_tcp_keepalive(fd: Socket, keepalive: &TcpKeepalive) -> io::Res } } + #[cfg(target_os = "nto")] + if let Some(time) = keepalive.time { + let secs = into_timeval(Some(time)); + unsafe { setsockopt(fd, libc::IPPROTO_TCP, KEEPALIVE_TIME, secs)? } + } + Ok(()) } -#[cfg(not(any(target_os = "haiku", target_os = "openbsd")))] +#[cfg(not(any(target_os = "haiku", target_os = "openbsd", target_os = "nto")))] fn into_secs(duration: Duration) -> c_int { min(duration.as_secs(), c_int::MAX as u64) as c_int } @@ -1032,6 +1049,7 @@ pub(crate) fn from_in6_addr(addr: in6_addr) -> Ipv6Addr { target_os = "openbsd", target_os = "redox", target_os = "solaris", + target_os = "nto", )))] pub(crate) const fn to_mreqn( multiaddr: &Ipv4Addr, @@ -1071,7 +1089,7 @@ impl crate::Socket { target_os = "illumos", target_os = "linux", target_os = "netbsd", - target_os = "openbsd" + target_os = "openbsd", ) ))] #[cfg_attr( @@ -1086,7 +1104,7 @@ impl crate::Socket { target_os = "illumos", target_os = "linux", target_os = "netbsd", - target_os = "openbsd" + target_os = "openbsd", ) ))) )] @@ -1102,7 +1120,7 @@ impl crate::Socket { target_os = "illumos", target_os = "linux", target_os = "netbsd", - target_os = "openbsd" + target_os = "openbsd", ))] pub(crate) fn _accept4(&self, flags: c_int) -> io::Result<(crate::Socket, SockAddr)> { // Safety: `accept4` initialises the `SockAddr` for us.