use std::{
fs::File,
io::{self, Read},
os::fd::{AsRawFd, OwnedFd},
process::{ChildStderr, ChildStdout},
};
pub(super) fn stdout(pipe: ChildStdout) -> File {
File::from(OwnedFd::from(pipe))
}
pub(super) fn stderr(pipe: ChildStderr) -> File {
File::from(OwnedFd::from(pipe))
}
pub(super) fn prepare(pipe: File) -> io::Result<File> {
let fd = pipe.as_raw_fd();
let mut metadata = std::mem::MaybeUninit::<libc::stat>::uninit();
if unsafe { libc::fstat(fd, metadata.as_mut_ptr()) } < 0 {
return Err(io::Error::last_os_error());
}
if unsafe { metadata.assume_init() }.st_mode & libc::S_IFMT != libc::S_IFIFO {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"native capture requires a pipe",
));
}
let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
if flags < 0 {
return Err(io::Error::last_os_error());
}
if unsafe { libc::fcntl(fd, libc::F_SETFL, flags | libc::O_NONBLOCK) } < 0 {
return Err(io::Error::last_os_error());
}
Ok(pipe)
}
pub(super) fn reader(pipe: File) -> File {
pipe
}
pub(super) fn shutdown(_pipe: &mut File) -> io::Result<()> {
Ok(())
}
pub(super) fn read(pipe: &mut File, buffer: &mut [u8]) -> io::Result<usize> {
pipe.read(buffer)
}