Skip to content

Commit 0db49f6

Browse files
jclulowThomasdezeeuw
authored andcommitted
illumos pipe handling fixes
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.
1 parent 1be481d commit 0db49f6

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

src/sys/unix/pipe.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> {
154154
target_os = "linux",
155155
target_os = "netbsd",
156156
target_os = "openbsd",
157+
target_os = "illumos",
157158
))]
158159
unsafe {
159160
if libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC | libc::O_NONBLOCK) != 0 {
@@ -192,6 +193,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> {
192193
target_os = "ios",
193194
target_os = "macos",
194195
target_os = "solaris",
196+
target_os = "illumos",
195197
)))]
196198
compile_error!("unsupported target for `mio::unix::pipe`");
197199

@@ -397,6 +399,7 @@ impl IntoRawFd for Receiver {
397399
}
398400
}
399401

402+
#[cfg(not(target_os = "illumos"))]
400403
fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
401404
let value = nonblocking as libc::c_int;
402405
if unsafe { libc::ioctl(fd, libc::FIONBIO, &value) } == -1 {
@@ -405,3 +408,25 @@ fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
405408
Ok(())
406409
}
407410
}
411+
412+
#[cfg(target_os = "illumos")]
413+
fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> {
414+
let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
415+
if flags < 0 {
416+
return Err(io::Error::last_os_error());
417+
}
418+
419+
let nflags = if nonblocking {
420+
flags | libc::O_NONBLOCK
421+
} else {
422+
flags & !libc::O_NONBLOCK
423+
};
424+
425+
if flags != nflags {
426+
if unsafe { libc::fcntl(fd, libc::F_SETFL, nflags) } < 0 {
427+
return Err(io::Error::last_os_error());
428+
}
429+
}
430+
431+
Ok(())
432+
}

0 commit comments

Comments
 (0)