fds.rs: port the open_cloexec family

This commit is contained in:
Johannes Altmanninger 2023-04-09 14:03:20 +02:00
parent a5cae59082
commit 483f893613

View File

@ -1,8 +1,23 @@
use crate::common::wcs2zstring;
use crate::ffi;
use crate::wchar::{wstr, L};
use crate::wutil::perror;
use libc::EINTR;
use libc::O_CLOEXEC;
use nix::unistd;
use std::ffi::CStr;
use std::io::{Read, Write};
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
pub const PIPE_ERROR: &wstr = L!("An error occurred while setting up pipe");
/// The first "high fd", which is considered outside the range of valid user-specified redirections
/// (like >&5).
pub const FIRST_HIGH_FD: RawFd = 10;
/// A sentinel value indicating no timeout.
pub const NO_TIMEOUT: u64 = u64::MAX;
/// A helper type for managing and automatically closing a file descriptor
///
/// This was implemented in rust as a port of the existing C++ code but it didn't take its place
@ -148,3 +163,25 @@ pub fn make_autoclose_pipes() -> Option<autoclose_pipes_t> {
})
}
}
/// Wide character version of open() that also sets the close-on-exec flag (atomically when
/// possible).
pub fn wopen_cloexec(pathname: &wstr, flags: i32, mode: libc::c_int) -> RawFd {
open_cloexec(wcs2zstring(pathname).as_c_str(), flags, mode)
}
/// Narrow versions of wopen_cloexec.
pub fn open_cloexec(path: &CStr, flags: i32, mode: libc::c_int) -> RawFd {
unsafe { libc::open(path.as_ptr(), flags | O_CLOEXEC, mode) }
}
/// Close a file descriptor \p fd, retrying on EINTR.
pub fn exec_close(fd: RawFd) {
assert!(fd >= 0, "Invalid fd");
while unsafe { libc::close(fd) } == -1 {
if errno::errno().0 != EINTR {
perror("close");
break;
}
}
}