Skip to content

Commit

Permalink
illumos pipe handling fixes
Browse files Browse the repository at this point in the history
illumos systems have had pipe2(2) since bug 3714 integrated in 2013, so
it is safe to expect and use that instead of pipe(2) plus a call to set
flags on the fd.  See also: https://www.illumos.org/issues/3714

While we have limited emulation of the BSD ioctl(FIONBIO) to make a file
descriptor non-blocking, it does not appear to work exactly as the test
suite expects.  Instead, use fcntl(F_SETFL) to set O_NONBLOCK.
  • Loading branch information
jclulow authored and Thomasdezeeuw committed Dec 8, 2020
1 parent 1be481d commit 0db49f6
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/sys/unix/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> {
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "illumos",
))]
unsafe {
if libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC | libc::O_NONBLOCK) != 0 {
Expand Down Expand Up @@ -192,6 +193,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> {
target_os = "ios",
target_os = "macos",
target_os = "solaris",
target_os = "illumos",
)))]
compile_error!("unsupported target for `mio::unix::pipe`");

Expand Down Expand Up @@ -397,6 +399,7 @@ impl IntoRawFd for Receiver {
}
}

#[cfg(not(target_os = "illumos"))]
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 {
Expand All @@ -405,3 +408,25 @@ fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
Ok(())
}
}

#[cfg(target_os = "illumos")]
fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
if flags < 0 {
return Err(io::Error::last_os_error());
}

let nflags = if nonblocking {
flags | libc::O_NONBLOCK
} else {
flags & !libc::O_NONBLOCK
};

if flags != nflags {
if unsafe { libc::fcntl(fd, libc::F_SETFL, nflags) } < 0 {
return Err(io::Error::last_os_error());
}
}

Ok(())
}

0 comments on commit 0db49f6

Please sign in to comment.