From e58c7ad3abf2592916040cc313e97a87c03da154 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Tue, 17 Jan 2023 21:38:12 +0100 Subject: [PATCH] Add support for QNX Neutrino Backport of commit 5b685144d4a970d54ceb35acc8f0fafb44a87588. --- Cargo.toml | 2 +- src/lib.rs | 20 ++++++++++++++++---- src/sockaddr.rs | 1 + src/socket.rs | 12 +++++++++++- src/sys/unix.rs | 37 ++++++++++++++++++++++++++++--------- 5 files changed, 57 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6784df9d..7427a76c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ rustdoc-args = ["--cfg", "docsrs"] features = ["all"] [target."cfg(unix)".dependencies] -libc = "0.2.124" +libc = "0.2.139" [target."cfg(windows)".dependencies] winapi = { version = "0.3.9", features = ["handleapi", "ws2ipdef", "ws2tcpip"] } diff --git a/src/lib.rs b/src/lib.rs index da9e8649..a2e2ffcb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -329,13 +329,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, } @@ -345,13 +351,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 16a4f0eb..9ce638e9 100644 --- a/src/sockaddr.rs +++ b/src/sockaddr.rs @@ -302,6 +302,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 87c143a3..7a754dc1 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)] @@ -1138,6 +1140,7 @@ impl Socket { target_os = "openbsd", target_os = "redox", target_os = "solaris", + target_os = "nto", )))] pub fn join_multicast_v4_n( &self, @@ -1167,6 +1170,7 @@ impl Socket { target_os = "openbsd", target_os = "redox", target_os = "solaris", + target_os = "nto", )))] pub fn leave_multicast_v4_n( &self, @@ -1198,6 +1202,7 @@ impl Socket { target_os = "openbsd", target_os = "redox", target_os = "fuchsia", + target_os = "nto", )))] pub fn join_ssm_v4( &self, @@ -1232,6 +1237,7 @@ impl Socket { target_os = "openbsd", target_os = "redox", target_os = "fuchsia", + target_os = "nto", )))] pub fn leave_ssm_v4( &self, @@ -1407,6 +1413,7 @@ impl Socket { target_os = "redox", target_os = "solaris", target_os = "windows", + target_os = "nto", )))] pub fn set_recv_tos(&self, recv_tos: bool) -> io::Result<()> { let recv_tos = if recv_tos { 1 } else { 0 }; @@ -1435,6 +1442,7 @@ impl Socket { target_os = "redox", target_os = "solaris", target_os = "windows", + target_os = "nto", )))] pub fn recv_tos(&self) -> io::Result { unsafe { @@ -1457,6 +1465,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), @@ -1480,6 +1489,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 8400d14e..c6b40c14 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -75,6 +75,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(all(feature = "all", not(target_os = "redox")))] pub(crate) use libc::IP_HDRINCL; #[cfg(not(any( @@ -85,6 +87,8 @@ pub(crate) use libc::IP_HDRINCL; target_os = "openbsd", target_os = "redox", target_os = "solaris", + target_os = "haiku", + target_os = "nto", )))] pub(crate) use libc::IP_RECVTOS; #[cfg(not(any( @@ -99,11 +103,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", @@ -112,6 +116,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, @@ -124,6 +129,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}; @@ -158,9 +164,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`. @@ -219,6 +230,7 @@ type IovLen = usize; target_os = "netbsd", target_os = "openbsd", target_os = "solaris", + target_os = "nto", target_vendor = "apple", ))] type IovLen = c_int; @@ -903,7 +915,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)? } @@ -930,10 +942,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_value() as u64) as c_int } @@ -1028,6 +1046,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) fn to_mreqn( multiaddr: &Ipv4Addr,