use errno::Errno;
use thiserror::Error;
pub mod info;
mod memstream;
use memstream::MemStream;
#[derive(Debug, Error)]
enum ErrorRepr {
#[error("libc error: {0}")]
LibC(#[from] Errno),
#[error(transparent)]
Memstream(#[from] memstream::Error),
#[error("failed to parse malloc_info XML output: {0}")]
Xml(#[from] quick_xml::DeError),
}
#[derive(Debug, Error)]
#[error(transparent)]
pub struct Error(#[from] ErrorRepr);
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(test)]
mod test {
use super::*;
#[tokio::test]
async fn call_from_async() {
let _ = tokio::task::spawn(async { malloc_info().expect("malloc_info") }).await;
}
}