use errno::Errno;
use thiserror::Error;
pub mod info;
#[cfg(all(target_os = "linux", target_env = "gnu"))]
mod memstream;
#[cfg(all(target_os = "linux", target_env = "gnu"))]
use memstream::MemStream;
#[derive(Debug, Error)]
enum ErrorRepr {
#[error("libc error: {0}")]
LibC(#[from] Errno),
#[cfg(all(target_os = "linux", target_env = "gnu"))]
#[error(transparent)]
Memstream(#[from] memstream::Error),
#[error("failed to parse malloc_info XML output: {0}")]
Xml(#[from] quick_xml::DeError),
#[cfg(not(all(target_os = "linux", target_env = "gnu")))]
#[error("malloc_info is only supported on linux-gnu targets")]
Unsupported,
}
#[derive(Debug, Error)]
#[error(transparent)]
pub struct Error(#[from] ErrorRepr);
#[cfg(all(target_os = "linux", target_env = "gnu"))]
pub fn malloc_info() -> Result<info::Malloc, Error> {
fn malloc_info() -> Result<info::Malloc, ErrorRepr> {
let mem_stream = MemStream::new()?;
let mut cursor = std::io::Cursor::new(mem_stream);
unsafe {
if libc::malloc_info(0, cursor.get_mut().fp) != 0 {
return Err(errno::errno().into());
}
if libc::fflush(cursor.get_mut().fp) != 0 {
return Err(errno::errno().into());
}
}
Ok(quick_xml::de::from_reader(&mut cursor)?)
}
malloc_info().map_err(Error::from)
}
#[cfg(not(all(target_os = "linux", target_env = "gnu")))]
pub fn malloc_info() -> Result<info::Malloc, Error> {
Err(ErrorRepr::Unsupported.into())
}