1use std::io::{Error, Result};
2pub(crate) use std::os::fd::{AsFd, BorrowedFd, OwnedFd};
3use std::os::fd::{AsRawFd, RawFd};
4
5use crate::{AsFdExt as _, Guard, Stdio};
6
7pub(crate) const DEV_NULL: &str = "/dev/null";
8
9impl Stdio {
10 fn as_raw_fd(&self) -> RawFd {
11 match self {
12 Stdio::Stdin => libc::STDIN_FILENO,
13 Stdio::Stdout => libc::STDOUT_FILENO,
14 Stdio::Stderr => libc::STDERR_FILENO,
15 }
16 }
17
18 unsafe fn set_raw_fd(&self, fd: RawFd) -> Result<()> {
19 if libc::dup2(fd, self.as_raw_fd()) < 0 {
20 return Err(Error::last_os_error());
21 }
22 Ok(())
23 }
24}
25
26impl AsFd for Stdio {
27 fn as_fd(&self) -> BorrowedFd<'static> {
28 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
29 }
30}
31
32impl AsFd for Guard {
33 fn as_fd(&self) -> BorrowedFd<'_> {
34 self.backup.as_ref().unwrap().borrow_file()
35 }
36}
37
38pub(crate) fn borrow_fd(file: &(impl AsFd + ?Sized)) -> BorrowedFd<'_> {
39 file.as_fd()
40}
41
42pub(crate) unsafe fn override_stdio(file: impl AsFd, stdio: Stdio) -> Result<OwnedFd> {
43 let backup = stdio.duplicate_file()?;
44 stdio.set_raw_fd(file.as_fd().as_raw_fd())?;
45 Ok(backup)
46}