From 48eceef0c356cf5efb13ed74bcdf825ea734e04c Mon Sep 17 00:00:00 2001 From: Petr Sumbera Date: Fri, 1 Sep 2023 11:41:16 +0200 Subject: [PATCH] Add Solaris operating system support (using flag mio_unsupported_force_poll_poll) --- src/sys/unix/mod.rs | 1 + src/sys/unix/net.rs | 3 ++- src/sys/unix/pipe.rs | 6 ++++-- src/sys/unix/tcp.rs | 1 + src/sys/unix/waker.rs | 3 +++ tests/tcp.rs | 9 ++++++++- tests/tcp_stream.rs | 16 ++++++++++++++-- tests/unix_datagram.rs | 4 ++++ tests/unix_stream.rs | 10 ++++++++++ 9 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/sys/unix/mod.rs b/src/sys/unix/mod.rs index eb268b9f4..2fdaa041e 100644 --- a/src/sys/unix/mod.rs +++ b/src/sys/unix/mod.rs @@ -105,6 +105,7 @@ cfg_os_poll! { target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", ))] pub(crate) mod pipe; } diff --git a/src/sys/unix/net.rs b/src/sys/unix/net.rs index 81b53a388..5e0318065 100644 --- a/src/sys/unix/net.rs +++ b/src/sys/unix/net.rs @@ -21,6 +21,7 @@ pub(crate) fn new_socket(domain: libc::c_int, socket_type: libc::c_int) -> io::R target_os = "linux", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", ))] let socket_type = socket_type | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC; @@ -139,7 +140,7 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, libc::socklen_ target_os = "espidf", ))] sin6_len: 0, - #[cfg(target_os = "illumos")] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] __sin6_src_id: 0, }; diff --git a/src/sys/unix/pipe.rs b/src/sys/unix/pipe.rs index 8e92dd37d..c03ec74ef 100644 --- a/src/sys/unix/pipe.rs +++ b/src/sys/unix/pipe.rs @@ -17,6 +17,7 @@ pub(crate) fn new_raw() -> io::Result<[RawFd; 2]> { target_os = "openbsd", target_os = "illumos", target_os = "redox", + target_os = "solaris", ))] unsafe { if libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC | libc::O_NONBLOCK) != 0 { @@ -64,6 +65,7 @@ pub(crate) fn new_raw() -> io::Result<[RawFd; 2]> { target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", target_os = "tvos", target_os = "watchos", target_os = "espidf", @@ -556,7 +558,7 @@ impl IntoRawFd for Receiver { } } -#[cfg(not(target_os = "illumos"))] +#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { let value = nonblocking as libc::c_int; if unsafe { libc::ioctl(fd, libc::FIONBIO, &value) } == -1 { @@ -566,7 +568,7 @@ fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { } } -#[cfg(target_os = "illumos")] +#[cfg(any(target_os = "illumos", target_os = "solaris"))] fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) }; if flags < 0 { diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs index c0bc40ad1..b25290d1c 100644 --- a/src/sys/unix/tcp.rs +++ b/src/sys/unix/tcp.rs @@ -67,6 +67,7 @@ pub(crate) fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, target_os = "linux", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", ))] let stream = { syscall!(accept4( diff --git a/src/sys/unix/waker.rs b/src/sys/unix/waker.rs index 4b73df32d..d89075b2c 100644 --- a/src/sys/unix/waker.rs +++ b/src/sys/unix/waker.rs @@ -25,6 +25,7 @@ mod fdbased { target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", ))] use crate::sys::unix::waker::pipe::WakerInternal; use crate::sys::Selector; @@ -205,6 +206,7 @@ pub use self::kqueue::Waker; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", ))] mod pipe { use crate::sys::unix::pipe; @@ -285,6 +287,7 @@ mod pipe { target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", ) ))] pub(crate) use self::pipe::WakerInternal; diff --git a/tests/tcp.rs b/tests/tcp.rs index 82ed6bcbf..2c61403d5 100644 --- a/tests/tcp.rs +++ b/tests/tcp.rs @@ -572,6 +572,8 @@ fn connect_error() { for event in &events { if event.token() == Token(0) { assert!(event.is_writable()); + // Solaris poll(2) says POLLHUP and POLLOUT are mutually exclusive. + #[cfg(not(target_os = "solaris"))] assert!(event.is_write_closed()); break 'outer; } @@ -698,7 +700,12 @@ fn write_shutdown() { // Now, shutdown the write half of the socket. socket.shutdown(Shutdown::Write).unwrap(); - wait!(poll, is_readable, true); + // POLLRDHUP isn't supported on Solaris + if cfg!(target_os = "solaris") { + wait!(poll, is_readable, false); + } else { + wait!(poll, is_readable, true); + } } struct MyHandler { diff --git a/tests/tcp_stream.rs b/tests/tcp_stream.rs index df9b3f2e3..aefeaa962 100644 --- a/tests/tcp_stream.rs +++ b/tests/tcp_stream.rs @@ -514,6 +514,10 @@ fn no_events_after_deregister() { windows, ignore = "fails on Windows; client read closed events are not triggered" )] +#[cfg_attr( + target_os = "solaris", + ignore = "POLLRDHUP isn't supported on Solaris" +)] fn tcp_shutdown_client_read_close_event() { let (mut poll, mut events) = init_with_poll(); let barrier = Arc::new(Barrier::new(2)); @@ -547,7 +551,7 @@ fn tcp_shutdown_client_read_close_event() { #[test] #[cfg_attr(windows, ignore = "fails; client write_closed events are not found")] #[cfg_attr( - any(target_os = "android", target_os = "illumos", target_os = "linux"), + any(target_os = "android", target_os = "illumos", target_os = "linux", target_os = "solaris"), ignore = "fails; client write_closed events are not found" )] fn tcp_shutdown_client_write_close_event() { @@ -581,6 +585,10 @@ fn tcp_shutdown_client_write_close_event() { } #[test] +#[cfg_attr( + target_os = "solaris", + ignore = "POLLRDHUP isn't supported on Solaris" +)] fn tcp_shutdown_server_write_close_event() { let (mut poll, mut events) = init_with_poll(); let barrier = Arc::new(Barrier::new(2)); @@ -611,6 +619,10 @@ fn tcp_shutdown_server_write_close_event() { } #[test] +#[cfg_attr( + target_os = "solaris", + ignore = "POLLRDHUP isn't supported on Solaris" +)] fn tcp_reset_close_event() { let (mut poll, mut events) = init_with_poll(); @@ -659,7 +671,7 @@ fn tcp_reset_close_event() { ignore = "fails on Windows; client close events are not found" )] #[cfg_attr( - any(target_os = "illumos"), + any(target_os = "illumos", target_os = "solaris"), ignore = "fails; client write_closed events are not found" )] fn tcp_shutdown_client_both_close_event() { diff --git a/tests/unix_datagram.rs b/tests/unix_datagram.rs index 1b05f5150..84ae5b16f 100644 --- a/tests/unix_datagram.rs +++ b/tests/unix_datagram.rs @@ -166,6 +166,10 @@ fn unix_datagram_pair() { } #[test] +#[cfg_attr( + target_os = "solaris", + ignore = "POLLRDHUP isn't supported on Solaris" +)] fn unix_datagram_shutdown() { let (mut poll, mut events) = init_with_poll(); let path1 = temp_file("unix_datagram_shutdown1"); diff --git a/tests/unix_stream.rs b/tests/unix_stream.rs index 9bb9d52fd..6436c3d55 100644 --- a/tests/unix_stream.rs +++ b/tests/unix_stream.rs @@ -186,6 +186,10 @@ fn unix_stream_peer_addr() { } #[test] +#[cfg_attr( + target_os = "solaris", + ignore = "POLLRDHUP isn't supported on Solaris" +)] fn unix_stream_shutdown_read() { let (mut poll, mut events) = init_with_poll(); let (handle, remote_addr) = new_echo_listener(1, "unix_stream_shutdown_read"); @@ -326,6 +330,8 @@ fn unix_stream_shutdown_both() { ); stream.shutdown(Shutdown::Both).unwrap(); + // Solaris never returns POLLHUP for sockets. + #[cfg(not(target_os = "solaris"))] expect_events( &mut poll, &mut events, @@ -361,6 +367,10 @@ fn unix_stream_shutdown_both() { } #[test] +#[cfg_attr( + target_os = "solaris", + ignore = "POLLRDHUP isn't supported on Solaris" +)] fn unix_stream_shutdown_listener_write() { let (mut poll, mut events) = init_with_poll(); let barrier = Arc::new(Barrier::new(2));