Set non-blocking IO more robustly.

- Check for errors.
 - Add O_NONBLOCK on top of any existing flags.

set_nonblock() is adapted from lang_tester:
e01072a0a4/src/tester.rs (L1041-L1048)
This commit is contained in:
Edd Barrett 2023-01-25 12:00:59 +00:00
parent 493ca3364a
commit 5c3825ffc5
No known key found for this signature in database

View File

@ -2,21 +2,28 @@ pub use self::imp::read2;
#[cfg(unix)]
mod imp {
use libc::{c_int, fcntl, F_GETFL, F_SETFL, O_NONBLOCK};
use std::io;
use std::io::prelude::*;
use std::mem;
use std::os::unix::prelude::*;
use std::process::{ChildStderr, ChildStdout};
fn set_nonblock(fd: c_int) -> io::Result<()> {
let flags = unsafe { fcntl(fd, F_GETFL) };
if flags == -1 || unsafe { fcntl(fd, F_SETFL, flags | O_NONBLOCK) } == -1 {
return Err(io::Error::last_os_error());
}
Ok(())
}
pub fn read2(
mut out_pipe: ChildStdout,
mut err_pipe: ChildStderr,
data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
) -> io::Result<()> {
unsafe {
libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
libc::fcntl(err_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
}
set_nonblock(out_pipe.as_raw_fd())?;
set_nonblock(err_pipe.as_raw_fd())?;
let mut out_done = false;
let mut err_done = false;