use super::Stdio;
use std::{
io,
os::fd::{FromRawFd, OwnedFd},
};
pub(super) struct State {
pub(super) ours: OwnedFd,
}
pub(super) fn setup_io(cmd: &mut std::process::Command) -> io::Result<State> {
let mut fds = [0; 2];
#[inline]
fn cvt(res: libc::c_int) -> io::Result<libc::c_int> {
if res == -1 {
Err(io::Error::last_os_error())
} else {
Ok(res)
}
}
cfg_if::cfg_if! {
if #[cfg(not(any(
target_env = "newlib",
target_os = "solaris",
target_os = "illumos",
target_os = "emscripten",
target_os = "fuchsia",
target_os = "l4re",
target_os = "linux",
target_os = "haiku",
target_os = "redox",
target_os = "vxworks",
target_os = "nto",
)))] {
#[inline]
unsafe fn set_cloexec(fd: libc::c_int) -> io::Result<()> {
cvt(unsafe { libc::ioctl(fd, libc::FIOCLEX) })?;
Ok(())
}
} else if #[cfg(any(
all(
target_env = "newlib",
not(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))
),
target_os = "solaris",
target_os = "emscripten",
target_os = "fuchsia",
target_os = "l4re",
target_os = "haiku",
target_os = "vxworks",
target_os = "nto",
))] {
#[inline]
unsafe fn set_cloexec(fd: libc::c_int) -> io::Result<()> {
let previous = cvt(unsafe { libc::fcntl(fd, libc::F_GETFD) })?;
let new = previous | libc::FD_CLOEXEC;
if new != previous {
cvt(unsafe { libc::fcntl(fd, libc::F_SETFD, new) })?;
}
Ok(())
}
} else {
}
}
let ours;
let theirs;
unsafe {
cfg_if::cfg_if! {
if #[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "redox",
target_os = "illumos"
))] {
cvt(libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC))?;
ours = std::os::fd::OwnedFd::from_raw_fd(fds[0]);
theirs = std::os::fd::OwnedFd::from_raw_fd(fds[1]);
} else {
use std::os::fd::AsRawFd;
cvt(libc::pipe(fds.as_mut_ptr()))?;
ours = std::os::fd::OwnedFd::from_raw_fd(fds[0]);
theirs = std::os::fd::OwnedFd::from_raw_fd(fds[1]);
set_cloexec(ours.as_raw_fd())?;
set_cloexec(theirs.as_raw_fd())?;
}
}
cmd.stderr(Stdio::from(theirs.try_clone()?))
.stdout(Stdio::from(theirs));
}
Ok(State { ours })
}