use std::io;
use std::path::Path;
use crate::platform::resources::InodeCapacity;
pub fn signals_fd_exhaustion(error: &io::Error) -> bool {
matches!(error.raw_os_error(), Some(libc::EMFILE | libc::ENFILE))
}
pub fn signals_storage_exhaustion(error: &io::Error) -> bool {
if matches!(error.kind(), io::ErrorKind::StorageFull) {
return true;
}
matches!(error.raw_os_error(), Some(libc::ENOSPC | libc::EDQUOT))
}
pub fn fd_exhaustion_error() -> io::Error {
io::Error::from_raw_os_error(libc::EMFILE)
}
pub fn storage_exhaustion_error() -> io::Error {
io::Error::from_raw_os_error(libc::ENOSPC)
}
pub fn inode_capacity(path: &Path) -> io::Result<Option<InodeCapacity>> {
use std::os::unix::ffi::OsStrExt;
let c_path = std::ffi::CString::new(path.as_os_str().as_bytes())
.map_err(|error| io::Error::new(io::ErrorKind::InvalidInput, error))?;
let mut stats: libc::statvfs = unsafe { std::mem::zeroed() };
let rc = unsafe { libc::statvfs(c_path.as_ptr(), &mut stats) };
if rc != 0 {
return Err(io::Error::last_os_error());
}
if stats.f_files == 0 {
return Ok(None);
}
#[allow(clippy::unnecessary_cast)]
Ok(Some(InodeCapacity {
total: stats.f_files as u64,
free: stats.f_favail as u64,
}))
}