use std::io; use std::os::fd::RawFd; use crate::SandboxError; const FIRST_FD_AFTER_STDIO: libc::c_uint = 3; pub fn keep_out_of_sandbox(kept_fds: &[RawFd]) -> Result<(), SandboxError> { mark_all_after_stdio_cloexec().map_err(SandboxError::InheritedFdsCloexec)?; for &fd in kept_fds { clear_cloexec(fd).map_err(|e| SandboxError::KeepFd(fd, e))?; } Ok(()) } fn mark_all_after_stdio_cloexec() -> io::Result<()> { let result = unsafe { libc::syscall( libc::SYS_close_range, FIRST_FD_AFTER_STDIO, libc::c_uint::MAX, libc::CLOSE_RANGE_CLOEXEC, ) }; if result < 0 { return Err(io::Error::last_os_error()); } Ok(()) } pub fn clear_cloexec(fd: RawFd) -> io::Result<()> { let flags = unsafe { libc::fcntl(fd, libc::F_GETFD) }; if flags < 0 { return Err(io::Error::last_os_error()); } if unsafe { libc::fcntl(fd, libc::F_SETFD, flags & !libc::FD_CLOEXEC) } < 0 { return Err(io::Error::last_os_error()); } Ok(()) }