1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//! Inspect Linux virtual memory metadata.
//!
//! The `mapped_region` module lets you see what VM regions are mapped.
//!
//! The `page_map` module lets you see physical info about each page (physical address, whether or
//! not it's swapped, etc).
extern crate byteorder;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate regex;

pub mod mapped_region;
pub mod page_map;

#[derive(Clone, Copy)]
pub enum ProcessId {
    /// The current process
    SelfPid,
    /// A numbered process, including the current process if you've already looked up its id
    Num(u32),
}

/// Return page size, if it is available on your platform. This can safely be cached; it will not
/// change during the lifetime of a process (per `sysconf(3)`.
///
/// Should work on any POSIX.1 platform (Linux, FreeBSD, macOS, ...).
pub fn page_size() -> Option<usize> {
    let raw_val = unsafe { libc::sysconf(libc::_SC_PAGESIZE) };

    match raw_val {
        // -1 means error, which would set errno, or unconfigured limit, which would not.
        // Fortunately we don't need to check errno in this case because pagesize is not a limit
        // that might be unconfigured, which would also lead to -1 being returned.
        -1 => None,
        // never less than 1 as per sysconf(3)
        n => Some(n as usize),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn page_size_works() {
        assert!(page_size().unwrap() > 0);
    }
}