Skip to content

Commit f6a20da

Browse files
authored
Add Solaris operating system support (#1724)
1 parent e80c3b2 commit f6a20da

File tree

13 files changed

+85
-22
lines changed

13 files changed

+85
-22
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ jobs:
152152
strategy:
153153
fail-fast: false
154154
matrix:
155-
target: ["armv7-sony-vita-newlibeabihf"]
155+
target: ["armv7-sony-vita-newlibeabihf", "sparcv9-sun-solaris", "x86_64-pc-solaris"]
156156
steps:
157157
- uses: actions/checkout@v3
158158
- uses: dtolnay/rust-toolchain@nightly

src/poll.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
#[cfg(all(unix, not(mio_unsupported_force_poll_poll), not(target_os = "vita")))]
1+
#[cfg(all(
2+
unix,
3+
not(mio_unsupported_force_poll_poll),
4+
not(any(target_os = "solaris", target_os = "vita"))
5+
))]
26
use std::os::unix::io::{AsRawFd, RawFd};
37
#[cfg(all(debug_assertions, not(target_os = "wasi")))]
48
use std::sync::atomic::{AtomicBool, Ordering};
@@ -423,7 +427,11 @@ impl Poll {
423427
}
424428
}
425429

426-
#[cfg(all(unix, not(mio_unsupported_force_poll_poll), not(target_os = "vita")))]
430+
#[cfg(all(
431+
unix,
432+
not(mio_unsupported_force_poll_poll),
433+
not(any(target_os = "solaris", target_os = "vita"))
434+
))]
427435
impl AsRawFd for Poll {
428436
fn as_raw_fd(&self) -> RawFd {
429437
self.registry.as_raw_fd()
@@ -710,7 +718,11 @@ impl fmt::Debug for Registry {
710718
}
711719
}
712720

713-
#[cfg(all(unix, not(mio_unsupported_force_poll_poll), not(target_os = "vita")))]
721+
#[cfg(all(
722+
unix,
723+
not(mio_unsupported_force_poll_poll),
724+
not(any(target_os = "solaris", target_os = "vita"))
725+
))]
714726
impl AsRawFd for Registry {
715727
fn as_raw_fd(&self) -> RawFd {
716728
self.selector.as_raw_fd()
@@ -721,7 +733,7 @@ cfg_os_poll! {
721733
#[cfg(all(
722734
unix,
723735
not(mio_unsupported_force_poll_poll),
724-
not(target_os = "vita"),
736+
not(any(target_os = "solaris", target_os = "vita")),
725737
))]
726738
#[test]
727739
pub fn as_raw_fd() {

src/sys/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ cfg_os_poll! {
5454
#[cfg(unix)]
5555
cfg_os_poll! {
5656
mod unix;
57+
#[allow(unused_imports)]
5758
pub use self::unix::*;
5859
}
5960

@@ -76,6 +77,7 @@ cfg_not_os_poll! {
7677
#[cfg(unix)]
7778
cfg_any_os_ext! {
7879
mod unix;
80+
#[cfg(feature = "os-ext")]
7981
pub use self::unix::SourceFd;
8082
}
8183

src/sys/unix/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ cfg_os_poll! {
1818
pub(crate) use self::selector::{event, Event, Events, Selector};
1919

2020
mod sourcefd;
21+
#[cfg(feature = "os-ext")]
2122
pub use self::sourcefd::SourceFd;
2223

2324
mod waker;
@@ -34,7 +35,7 @@ cfg_os_poll! {
3435

3536
cfg_io_source! {
3637
// Both `kqueue` and `epoll` don't need to hold any user space state.
37-
#[cfg(not(any(mio_unsupported_force_poll_poll, target_os = "vita")))]
38+
#[cfg(not(any(mio_unsupported_force_poll_poll, target_os = "solaris", target_os = "vita")))]
3839
mod stateless_io_source {
3940
use std::io;
4041
use std::os::unix::io::RawFd;
@@ -87,10 +88,10 @@ cfg_os_poll! {
8788
}
8889
}
8990

90-
#[cfg(not(any(mio_unsupported_force_poll_poll, target_os = "vita")))]
91+
#[cfg(not(any(mio_unsupported_force_poll_poll, target_os = "solaris",target_os = "vita")))]
9192
pub(crate) use self::stateless_io_source::IoSourceState;
9293

93-
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))]
94+
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "solaris", target_os = "vita"))]
9495
pub(crate) use self::selector::IoSourceState;
9596
}
9697

@@ -105,6 +106,7 @@ cfg_os_poll! {
105106
target_os = "netbsd",
106107
target_os = "openbsd",
107108
target_os = "redox",
109+
target_os = "solaris",
108110
target_os = "vita",
109111
))]
110112
pub(crate) mod pipe;
@@ -118,6 +120,7 @@ cfg_not_os_poll! {
118120

119121
cfg_any_os_ext! {
120122
mod sourcefd;
123+
#[cfg(feature = "os-ext")]
121124
pub use self::sourcefd::SourceFd;
122125
}
123126
}

src/sys/unix/net.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub(crate) fn new_socket(domain: libc::c_int, socket_type: libc::c_int) -> io::R
2121
target_os = "linux",
2222
target_os = "netbsd",
2323
target_os = "openbsd",
24+
target_os = "solaris",
2425
))]
2526
let socket_type = socket_type | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
2627

@@ -149,7 +150,7 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, libc::socklen_
149150
sin6_len: 0,
150151
#[cfg(target_os = "vita")]
151152
sin6_vport: addr.port().to_be(),
152-
#[cfg(target_os = "illumos")]
153+
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
153154
__sin6_src_id: 0,
154155
};
155156

src/sys/unix/pipe.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub(crate) fn new_raw() -> io::Result<[RawFd; 2]> {
1717
target_os = "openbsd",
1818
target_os = "illumos",
1919
target_os = "redox",
20+
target_os = "solaris",
2021
target_os = "vita",
2122
))]
2223
unsafe {
@@ -68,6 +69,7 @@ pub(crate) fn new_raw() -> io::Result<[RawFd; 2]> {
6869
target_os = "tvos",
6970
target_os = "watchos",
7071
target_os = "espidf",
72+
target_os = "solaris",
7173
target_os = "vita",
7274
)))]
7375
compile_error!("unsupported target for `mio::unix::pipe`");
@@ -558,7 +560,7 @@ impl IntoRawFd for Receiver {
558560
}
559561
}
560562

561-
#[cfg(not(any(target_os = "illumos", target_os = "vita")))]
563+
#[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "vita")))]
562564
fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
563565
let value = nonblocking as libc::c_int;
564566
if unsafe { libc::ioctl(fd, libc::FIONBIO, &value) } == -1 {
@@ -568,7 +570,7 @@ fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
568570
}
569571
}
570572

571-
#[cfg(any(target_os = "illumos", target_os = "vita"))]
573+
#[cfg(any(target_os = "illumos", target_os = "solaris", target_os = "vita"))]
572574
fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
573575
let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
574576
if flags < 0 {

src/sys/unix/selector/mod.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,22 @@ mod epoll;
2020
))]
2121
pub(crate) use self::epoll::{event, Event, Events, Selector};
2222

23-
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))]
23+
#[cfg(any(
24+
mio_unsupported_force_poll_poll,
25+
target_os = "solaris",
26+
target_os = "vita"
27+
))]
2428
mod poll;
2529

26-
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))]
30+
#[cfg(any(
31+
mio_unsupported_force_poll_poll,
32+
target_os = "solaris",
33+
target_os = "vita"
34+
))]
2735
pub(crate) use self::poll::{event, Event, Events, Selector};
2836

2937
cfg_io_source! {
30-
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))]
38+
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "solaris", target_os = "vita"))]
3139
pub(crate) use self::poll::IoSourceState;
3240
}
3341

src/sys/unix/tcp.rs

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub(crate) fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream,
6767
target_os = "linux",
6868
target_os = "netbsd",
6969
target_os = "openbsd",
70+
target_os = "solaris",
7071
))]
7172
let stream = {
7273
syscall!(accept4(

src/sys/unix/waker.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
target_os = "watchos",
1111
)
1212
)),
13-
not(target_os = "vita"),
13+
not(any(target_os = "solaris", target_os = "vita")),
1414
))]
1515
mod fdbased {
1616
#[cfg(all(
@@ -63,7 +63,7 @@ mod fdbased {
6363
target_os = "watchos",
6464
)
6565
)),
66-
not(target_os = "vita"),
66+
not(any(target_os = "solaris", target_os = "vita")),
6767
))]
6868
pub use self::fdbased::Waker;
6969

@@ -207,6 +207,7 @@ pub use self::kqueue::Waker;
207207
target_os = "netbsd",
208208
target_os = "openbsd",
209209
target_os = "redox",
210+
target_os = "solaris",
210211
target_os = "vita",
211212
))]
212213
mod pipe {
@@ -253,7 +254,11 @@ mod pipe {
253254
}
254255
}
255256

256-
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))]
257+
#[cfg(any(
258+
mio_unsupported_force_poll_poll,
259+
target_os = "solaris",
260+
target_os = "vita"
261+
))]
257262
pub fn ack_and_reset(&self) {
258263
self.empty();
259264
}
@@ -291,11 +296,16 @@ mod pipe {
291296
target_os = "redox",
292297
)
293298
),
299+
target_os = "solaris",
294300
target_os = "vita",
295301
))]
296302
pub(crate) use self::pipe::WakerInternal;
297303

298-
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))]
304+
#[cfg(any(
305+
mio_unsupported_force_poll_poll,
306+
target_os = "solaris",
307+
target_os = "vita"
308+
))]
299309
mod poll {
300310
use crate::sys::Selector;
301311
use crate::Token;
@@ -321,5 +331,9 @@ mod poll {
321331
}
322332
}
323333

324-
#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))]
334+
#[cfg(any(
335+
mio_unsupported_force_poll_poll,
336+
target_os = "solaris",
337+
target_os = "vita"
338+
))]
325339
pub use self::poll::Waker;

tests/tcp.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,8 @@ fn connect_error() {
572572
for event in &events {
573573
if event.token() == Token(0) {
574574
assert!(event.is_writable());
575+
// Solaris poll(2) says POLLHUP and POLLOUT are mutually exclusive.
576+
#[cfg(not(target_os = "solaris"))]
575577
assert!(event.is_write_closed());
576578
break 'outer;
577579
}
@@ -698,7 +700,12 @@ fn write_shutdown() {
698700
// Now, shutdown the write half of the socket.
699701
socket.shutdown(Shutdown::Write).unwrap();
700702

701-
wait!(poll, is_readable, true);
703+
// POLLRDHUP isn't supported on Solaris
704+
if cfg!(target_os = "solaris") {
705+
wait!(poll, is_readable, false);
706+
} else {
707+
wait!(poll, is_readable, true);
708+
}
702709
}
703710

704711
struct MyHandler {

tests/tcp_stream.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ fn no_events_after_deregister() {
514514
windows,
515515
ignore = "fails on Windows; client read closed events are not triggered"
516516
)]
517+
#[cfg_attr(target_os = "solaris", ignore = "POLLRDHUP isn't supported on Solaris")]
517518
fn tcp_shutdown_client_read_close_event() {
518519
let (mut poll, mut events) = init_with_poll();
519520
let barrier = Arc::new(Barrier::new(2));
@@ -547,7 +548,12 @@ fn tcp_shutdown_client_read_close_event() {
547548
#[test]
548549
#[cfg_attr(windows, ignore = "fails; client write_closed events are not found")]
549550
#[cfg_attr(
550-
any(target_os = "android", target_os = "illumos", target_os = "linux"),
551+
any(
552+
target_os = "android",
553+
target_os = "illumos",
554+
target_os = "solaris",
555+
target_os = "linux"
556+
),
551557
ignore = "fails; client write_closed events are not found"
552558
)]
553559
fn tcp_shutdown_client_write_close_event() {
@@ -581,6 +587,7 @@ fn tcp_shutdown_client_write_close_event() {
581587
}
582588

583589
#[test]
590+
#[cfg_attr(target_os = "solaris", ignore = "POLLRDHUP isn't supported on Solaris")]
584591
fn tcp_shutdown_server_write_close_event() {
585592
let (mut poll, mut events) = init_with_poll();
586593
let barrier = Arc::new(Barrier::new(2));
@@ -611,6 +618,7 @@ fn tcp_shutdown_server_write_close_event() {
611618
}
612619

613620
#[test]
621+
#[cfg_attr(target_os = "solaris", ignore = "POLLRDHUP isn't supported on Solaris")]
614622
fn tcp_reset_close_event() {
615623
let (mut poll, mut events) = init_with_poll();
616624

@@ -659,7 +667,7 @@ fn tcp_reset_close_event() {
659667
ignore = "fails on Windows; client close events are not found"
660668
)]
661669
#[cfg_attr(
662-
any(target_os = "illumos"),
670+
any(target_os = "illumos", target_os = "solaris"),
663671
ignore = "fails; client write_closed events are not found"
664672
)]
665673
fn tcp_shutdown_client_both_close_event() {

tests/unix_datagram.rs

+1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ fn unix_datagram_pair() {
166166
}
167167

168168
#[test]
169+
#[cfg_attr(target_os = "solaris", ignore = "POLLRDHUP isn't supported on Solaris")]
169170
fn unix_datagram_shutdown() {
170171
let (mut poll, mut events) = init_with_poll();
171172
let path1 = temp_file("unix_datagram_shutdown1");

tests/unix_stream.rs

+4
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ fn unix_stream_peer_addr() {
186186
}
187187

188188
#[test]
189+
#[cfg_attr(target_os = "solaris", ignore = "POLLRDHUP isn't supported on Solaris")]
189190
fn unix_stream_shutdown_read() {
190191
let (mut poll, mut events) = init_with_poll();
191192
let (handle, remote_addr) = new_echo_listener(1, "unix_stream_shutdown_read");
@@ -326,6 +327,8 @@ fn unix_stream_shutdown_both() {
326327
);
327328

328329
stream.shutdown(Shutdown::Both).unwrap();
330+
// Solaris never returns POLLHUP for sockets.
331+
#[cfg(not(target_os = "solaris"))]
329332
expect_events(
330333
&mut poll,
331334
&mut events,
@@ -361,6 +364,7 @@ fn unix_stream_shutdown_both() {
361364
}
362365

363366
#[test]
367+
#[cfg_attr(target_os = "solaris", ignore = "POLLRDHUP isn't supported on Solaris")]
364368
fn unix_stream_shutdown_listener_write() {
365369
let (mut poll, mut events) = init_with_poll();
366370
let barrier = Arc::new(Barrier::new(2));

0 commit comments

Comments
 (0)