use std::collections::BTreeSet;
use std::os::unix::prelude::*;
use std::fs;
use std::path::Path;
use std::panic;
use failure::{format_err, ResultExt};
use nix::unistd;
use crate::util;
pub fn close_all_fds(keep_fds: &BTreeSet<RawFd>) -> Result<(), failure::Error> {
let fd_dir = fs::read_dir(Path::new(r"/proc/self/fd/")).context("error reading /proc/self/fd/")?;
let mut fds = BTreeSet::new();
for dir_entry_result in fd_dir {
let fd_name = dir_entry_result.context("error reading /proc/self/fd/")?.file_name();
let fd = fd_name
.to_string_lossy()
.parse::<RawFd>()
.with_context(|_| format_err!("invalid fd number in /proc/self/fd/: {:?}", fd_name))?;
fds.insert(fd);
}
for fd in fds.difference(&keep_fds) {
match unistd::close(*fd) {
Ok(()) => (),
Err(nix::Error::EBADF) => (),
Err(error) => util::convert_nix(Err(error))?,
}
}
Ok(())
}
pub(crate) fn init_malloc() {
drop(Box::new(1));
}
pub(crate) fn configure_panic_hook() {
let default_panic_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info: &panic::PanicInfo<'_>| {
default_panic_hook(panic_info);
panic!("aborting")
}));
}