Auto merge of #11624 - vext01:poll-loop-fixes, r=ehuss

Poll loop fixes

### What does this PR try to resolve?

A couple of minor issues. See individual commits.

### How should we test and review this PR?

The existing test suite should have sufficient coverage.

### Additional information

(I have 5 apparently unrelated failures locally when running `cargo test`)
This commit is contained in:
bors 2023-03-20 12:42:45 +00:00
commit 16d0495d29

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;
@ -32,7 +39,7 @@ mod imp {
let mut errfd = 1;
while nfds > 0 {
// wait for either pipe to become readable using `select`
// wait for either pipe to become readable using `poll`
let r = unsafe { libc::poll(fds.as_mut_ptr(), nfds, -1) };
if r == -1 {
let err = io::Error::last_os_error();