### Example Usage of WithCurrentSystemInfo Source: https://github.com/eminence/procfs/blob/master/_autodocs/1-core-types.md Demonstrates how to obtain the current process's statistics and retrieve RSS bytes using the WithCurrentSystemInfo trait. This requires importing the trait and getting the current process. ```rust use procfs::WithCurrentSystemInfo; let me = procfs::process::Process::myself()?; let stat = me.stat()?; let bytes = stat.rss_bytes().get(); // Использует текущую информацию о системе ``` -------------------------------- ### Example Usage of Process Creation Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Demonstrates how to create a Process instance for the current process or a specific PID. ```rust use procfs::process::Process; // Текущий процесс let me = Process::myself()?; println!("My PID: {}", me.pid); // Конкретный процесс let init = Process::new(1)?; println!("Init PID: {}", init.pid); ``` -------------------------------- ### Integrate Procfs with Chrono for Boot Time Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Enable the 'chrono' feature in Cargo.toml to use the `chrono` crate for handling timestamps. This example retrieves and formats the system boot time. ```toml [dependencies] procfs = { version = "0.18", features = ["chrono"] } chrono = "0.4" ``` ```rust use procfs::boot_time; let boot_dt = boot_time()?; println!("System booted at: {}", boot_dt.format("%Y-%m-%d %H:%M:%S")); ``` -------------------------------- ### Retrieve Disk Statistics Source: https://github.com/eminence/procfs/blob/master/_autodocs/6-disk-and-network.md Fetches disk I/O statistics for all disks from the /proc/diskstats file. The example demonstrates how to iterate through the results and calculate read/write throughput. ```rust let diskstats = procfs::diskstats()?; for disk in diskstats { let throughput_read = disk.sectors_read as f64 * 512.0 / disk.time_reading.max(1) as f64; let throughput_write = disk.sectors_written as f64 * 512.0 / disk.time_writing.max(1) as f64; println!("{}: read={:.2} MB/s, write={:.2} MB/s", disk.name, throughput_read / 1_000_000.0, throughput_write / 1_000_000.0 ); } ``` -------------------------------- ### Get System Info using LocalSystemInfo Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Retrieve system information using the convenient `current_system_info` function provided by the procfs crate. This function automatically detects and provides system-specific details. ```rust use procfs::current_system_info; let system_info = current_system_info(); println!("Boot time: {}", system_info.boot_time_secs()); println!("Ticks/sec: {}", system_info.ticks_per_second()); println!("Page size: {}", system_info.page_size()); ``` -------------------------------- ### Safely Compare Process Identities Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Illustrates the danger of comparing PIDs directly due to potential PID reuse. Shows the correct method of comparing process identity using start time. ```Rust // WRONG: PID may have been reused let old_pid = 1234; // ... time passes ... if let Ok(proc) = procfs::process::Process::new(old_pid) { // This might be a DIFFERENT process! } // RIGHT: Check actual identity or use inode let old_stat = /* saved stat */; if let Ok(proc) = procfs::process::Process::new(pid) { if let Ok(new_stat) = proc.stat() { if old_stat.starttime == new_stat.starttime { // Same process } } } ``` -------------------------------- ### Integrate Procfs with Anyhow for Error Handling Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Procfs's `ProcError` integrates seamlessly with error handling libraries like `anyhow`. This example demonstrates retrieving a process's command name using `anyhow::Result`. ```rust use procfs::ProcResult; use anyhow::Result; fn example() -> Result { let process = procfs::process::Process::myself()?; let stat = process.stat()?; Ok(stat.comm) } ``` -------------------------------- ### WithCurrentSystemInfo Trait Source: https://github.com/eminence/procfs/blob/master/_autodocs/1-core-types.md The `WithCurrentSystemInfo` trait is a specialization of `WithSystemInfo` that uses the current system information available within the `procfs` crate. It provides a `get` method for easy access to the derived output. ```APIDOC ## Trait: WithCurrentSystemInfo<'a> ### Description Similar to `WithSystemInfo`, but uses the current system information available within the `procfs` crate. ### Methods - `get(self) -> Self::Output`: Retrieves the derived output using the current system information. ### Requirements - Implements `WithSystemInfo<'a>`. - `Sized`. ### Example ```rust use procfs::WithCurrentSystemInfo; let me = procfs::process::Process::myself()?; let stat = me.stat()?; let bytes = stat.rss_bytes().get(); // Uses current system info ``` ``` -------------------------------- ### Integrate Procfs with Serde for JSON Serialization Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Enable the 'serde1' feature in Cargo.toml to serialize procfs data structures into JSON using `serde_json`. This example serializes Meminfo data. ```toml [dependencies] procfs = { version = "0.18", features = ["serde1"] } serde_json = "1.0" ``` ```rust use procfs::Meminfo; use serde_json::json; let meminfo = Meminfo::current()?; let json = serde_json::to_string(&meminfo)?; println!("{}", json); ``` -------------------------------- ### Get Current Kernel Stats Source: https://github.com/eminence/procfs/blob/master/_autodocs/4-memory-cpu-info.md Retrieves the current kernel statistics from the /proc/stat file. Ensure the procfs crate is imported. ```rust use procfs::KernelStats; let stat = KernelStats::current()?; println!("Total CPU time:"); println!(" User: {}", stat.total.user); println!(" System: {}", stat.total.system); println!(" Idle: {}", stat.total.idle); println!("Boot time: {}", stat.btime); println!("Context switches: {}", stat.ctxt); ``` -------------------------------- ### Get Current Process Memory Usage in Rust Source: https://github.com/eminence/procfs/blob/master/README.md Retrieves and displays the current process's PID, memory page size, total virtual memory, and resident set size. Requires the procfs crate. ```rust use procfs::process::Process; fn main() { let me = Process::myself().unwrap(); let me_stat = me.stat().unwrap(); println!("PID: {}", me.pid); let page_size = procfs::page_size(); println!("Memory page size: {}", page_size); println!("== Data from /proc/self/stat:"); println!("Total virtual memory used: {} bytes", me_stat.vsize); println!( "Total resident set: {} pages ({} bytes)", me_stat.rss, me_stat.rss * page_size ); } ``` -------------------------------- ### Test Stat Parsing with Mock Data Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Utilize the `FromRead` trait and `std::io::Cursor` to mock /proc data for testing purposes. This example demonstrates parsing a stat line. ```rust #[cfg(test)] mod tests { use procfs::FromRead; use std::io::Cursor; #[test] fn test_stat_parsing() { let stat_line = "1 (init) S 0 1 1 0 -1 4194304 ..."; let stat = procfs::process::Stat::from_read(Cursor::new(stat_line)); assert!(stat.is_ok()); } } ``` -------------------------------- ### Process Creation Methods Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Provides methods to create Process instances for a given PID or the current process. ```rust impl Process { pub fn new(pid: i32) -> ProcResult; pub fn myself() -> ProcResult; } ``` -------------------------------- ### List Mounted Filesystems in Rust Source: https://github.com/eminence/procfs/blob/master/_autodocs/7-usage-patterns.md Iterates through all mounted filesystems and prints their device, mount point, type, and options. Excludes temporary filesystems like tmpfs and devtmpfs. Requires the `procfs` crate. ```rust use procfs::MountEntry; fn list_filesystems() -> procfs::ProcResult<()> { let mounts = procfs::mounts()?; println!("Device Mount Point Type Options"); println!("{:-45} {:-20} {:-10} {}", "-", "-", "-", "-"); for mount in mounts { if mount.fs_vfstype != "tmpfs" && mount.fs_vfstype != "devtmpfs" { println!("{:<20} {:<22} {:<10} {}", mount.fs_spec, mount.fs_file, mount.fs_vfstype, mount.fs_mntops.split(',').next().unwrap_or("") ); } } Ok(()) } fn get_mount_point(device: &str) -> procfs::ProcResult> { for mount in procfs::mounts()? { if mount.fs_spec == device { return Ok(Some(mount.fs_file)); } } Ok(None) } ``` -------------------------------- ### Read System Information Source: https://github.com/eminence/procfs/blob/master/_autodocs/README.md Fetches and displays total memory, core count, and load average. Requires importing `Meminfo`, `CpuInfo`, and `LoadAverage`. ```rust use procfs::{Meminfo, CpuInfo, LoadAverage}; let meminfo = Meminfo::current()?; let cpuinfo = CpuInfo::current()?; let load = LoadAverage::current()?; println!("Memory: {} MB", meminfo.mem_total / 1024 / 1024); println!("Cores: {}", cpuinfo.num_cores()); println!("Load: {}", load.one); ``` -------------------------------- ### List Disk Partitions in Rust Source: https://github.com/eminence/procfs/blob/master/_autodocs/7-usage-patterns.md Retrieves and displays information about disk partitions, including their names and total size in megabytes. Requires the `procfs` crate. ```rust fn list_partitions() -> procfs::ProcResult<()> { let partitions = procfs::partitions()?; println!("Device Size(MB)"); println!("{:-15} {}", "-", "-"); for part in partitions { let size_mb = part.blocks as f64 * 1024.0 / 1024.0; println!("{:<15} {:.2}", part.name, size_mb); } Ok(()) } ``` -------------------------------- ### Handle Optional Fields Safely Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Demonstrates how to safely access fields that may not exist on all kernel versions. Uses `match` to handle `Option` types and avoid panics. ```Rust // WRONG: panic on old kernels let umask = process.status()?.umask.unwrap(); // RIGHT match process.status()?.umask { Some(u) => println!("Umask: {:o}", u), None => println!("Umask not available"), } ``` -------------------------------- ### Parse /proc/uptime and String Data with FromRead Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Demonstrates parsing /proc/uptime from a file and also parsing uptime data directly from a string using the `FromRead` trait. ```rust use procfs::FromRead; use std::fs::File; // Parse /proc/uptime let file = File::open("/proc/uptime")?; let uptime = procfs::Uptime::from_read(file)?; // Parse from string let data = "123.45 678.90\n"; let uptime = procfs::Uptime::from_read(data.as_bytes())?; ``` -------------------------------- ### Process Creation Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Provides methods to create Process objects for a given PID or the current process. ```APIDOC ## Process Creation ### Description Provides methods to create `Process` objects for a given PID or the current process. ### Methods #### `new(pid: i32)` - **Parameters** - `pid` (i32) - The Process ID. - **Returns** - `ProcResult` - A `Process` object for the specified PID. - **Description** Creates a `Process` object for the given PID. #### `myself()` - **Parameters** - None - **Returns** - `ProcResult` - A `Process` object for the current process. - **Description** Creates a `Process` object for the current process. ### Example ```rust use procfs::process::Process; // Current process let me = Process::myself()?; println!("My PID: {}", me.pid); // Specific process let init = Process::new(1)?; println!("Init PID: {}", init.pid); ``` ``` -------------------------------- ### Monitor Disk I/O Activity in Rust Source: https://github.com/eminence/procfs/blob/master/_autodocs/7-usage-patterns.md Calculates and displays the read and write speeds in MB/s for each disk device, excluding loop and RAM devices. It also shows the I/O progress. Requires the `procfs` crate. ```rust use procfs::DiskStat; fn monitor_disk_io() -> procfs::ProcResult<()> { let diskstats = procfs::diskstats()?; println!("Device Read(MB/s) Write(MB/s) I/O Progress"); println!("{:-15} {:-15} {:-15} {}", "-", "-", "-", "-"); for disk in diskstats { // Пропускаем loop и ram устройства if disk.name.starts_with("loop") || disk.name.starts_with("ram") { continue; } // Расчёт пропускной способности (секторы -> байты) let read_speed = disk.sectors_read as f64 * 512.0 / 1_000_000.0; let write_speed = disk.sectors_written as f64 * 512.0 / 1_000_000.0; println!("{:<15} {:<15.2} {:<15.2} {}", disk.name, read_speed, write_speed, disk.in_progress ); } Ok(()) } ``` -------------------------------- ### Safely Read Process Command Line Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Safely read a process's command line, handling permission denied and not found errors gracefully. Returns None if the process is inaccessible or has exited. ```rust use procfs::process::Process; fn safe_read_process(pid: i32) -> procfs::ProcResult> { match Process::new(pid) { Ok(process) => { match process.cmdline() { Ok(args) => Ok(Some(args.join(" "))), Err(procfs::ProcError::PermissionDenied(_)) => { // This is expected for other users' processes Ok(None) } Err(e) => Err(e), } } Err(procfs::ProcError::NotFound(_)) => { // Process exited Ok(None) } Err(e) => Err(e), } } ``` -------------------------------- ### Correctly Calculate RSS in Bytes Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Highlights the pitfall of assuming RSS is in bytes. Shows the correct way to calculate Resident Set Size in bytes by multiplying page count with page size. ```Rust // WRONG: rss is in pages, not bytes let rss_pages = stat.rss; // let bytes = rss_pages; // This is wrong! // RIGHT let page_size = procfs::page_size(); let rss_bytes = rss_pages * page_size; ``` -------------------------------- ### Thread-Local Caching of Boot Time Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md The `boot_time_secs()` function caches its result in thread-local storage for faster subsequent calls within the same thread. ```rust let t1 = procfs::boot_time_secs()?; let t2 = procfs::boot_time_secs()?; // Instant, cached ``` -------------------------------- ### List Processes on Same TTY in Rust Source: https://github.com/eminence/procfs/blob/master/README.md Prints processes running on the same TTY as the calling process, similar to 'ps' default mode. Requires the procfs crate. ```rust fn main() { let me = procfs::process::Process::myself().unwrap(); let me_stat = me.stat().unwrap(); let tps = procfs::ticks_per_second(); println!("{: >5} {: <8} {: >8} {}", "PID", "TTY", "TIME", "CMD"); let tty = format!("pty/{}", me_stat.tty_nr().1); for prc in procfs::process::all_processes().unwrap() { let prc = prc.unwrap(); let stat = prc.stat().unwrap(); if stat.tty_nr == me_stat.tty_nr { // total_time is in seconds let total_time = (stat.utime + stat.stime) as f32 / (tps as f32); println!( "{: >5} {: <8} {: >8} {}", stat.pid, tty, total_time, stat.comm ); } } } ``` -------------------------------- ### Inspect Network Connections Source: https://github.com/eminence/procfs/blob/master/_autodocs/README.md Lists all TCP network connections, displaying local and remote addresses along with their state. Requires importing `procfs::net` and `std::net::Ipv4Addr`. ```rust use procfs::net; use std::net::Ipv4Addr; for entry in net::tcp()? { let local = Ipv4Addr::from(entry.local_address.0); let remote = Ipv4Addr::from(entry.remote_address.0); println!("{}:{} -> {}:{} ({})", local, entry.local_address.1, remote, entry.remote_address.1, entry.state ); } ``` -------------------------------- ### Handle System Call Errors in Rust Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Demonstrates correct error handling for system calls that might fail. Avoids panics by using the `?` operator or pattern matching. ```Rust // WRONG: Can panic let mems = procfs::mounts().unwrap(); // RIGHT let mems = procfs::mounts()?; ``` -------------------------------- ### KernelStats::current() Source: https://github.com/eminence/procfs/blob/master/_autodocs/4-memory-cpu-info.md Retrieves the current kernel statistics from the /proc/stat file. This method provides a snapshot of system-wide CPU time, process counts, and boot time. ```APIDOC ## KernelStats::current() ### Description Fetches the current kernel statistics from the `/proc/stat` file. This includes total CPU time, context switches, boot time, and process counts. ### Method `KernelStats::current()` ### Parameters None ### Response - **ProcResult** - A result containing the `KernelStats` struct on success, or an error. ### Request Example ```rust use procfs::KernelStats; let stat = KernelStats::current()?; println!("Total CPU time:"); println!(" User: {}", stat.total.user); println!(" System: {}", stat.total.system); println!(" Idle: {}", stat.total.idle); println!("Boot time: {}", stat.btime); println!("Context switches: {}", stat.ctxt); ``` ### Response Example ```json { "cpu_time": [ { "user": 1000, "nice": 0, "system": 500, "idle": 2000, "iowait": null, "irq": null, "softirq": null, "steal": null, "guest": null, "guest_nice": null }, { "user": 1200, "nice": 0, "system": 600, "idle": 2200, "iowait": null, "irq": null, "softirq": null, "steal": null, "guest": null, "guest_nice": null } ], "total": { "user": 2200, "nice": 0, "system": 1100, "idle": 4200, "iowait": null, "irq": null, "softirq": null, "steal": null, "guest": null, "guest_nice": null }, "intr": 5000, "ctxt": 15000, "btime": 1678886400, "processes": 300, "procs_running": 5, "procs_blocked": 10 } ``` ``` -------------------------------- ### Enable Serde1 Feature for Procfs Source: https://github.com/eminence/procfs/blob/master/_autodocs/README.md Add this to your Cargo.toml to enable serialization support for procfs structs. ```toml [dependencies] procfs = { version = "0.18", features = ["serde1"] } ``` -------------------------------- ### Read Current Process Information Source: https://github.com/eminence/procfs/blob/master/_autodocs/README.md Retrieves and prints memory usage and state for the current process. Requires importing `Process` and `WithCurrentSystemInfo`. ```rust use procfs::process::Process; use procfs::WithCurrentSystemInfo; let me = Process::myself()?; let stat = me.stat()?; let status = me.status()?; println!("Process: {} ({})", stat.comm, me.pid); println!("Memory: {} MB", status.vmrss.unwrap_or(0) / 1024); println!("State: {:?}", stat.state()); ``` -------------------------------- ### Handle Procfs Errors Source: https://github.com/eminence/procfs/blob/master/_autodocs/README.md Demonstrates how to handle potential errors when creating a Process object and accessing its stat information. Catches specific errors like PermissionDenied and NotFound. ```rust use procfs::{ProcError, process::Process}; match Process::new(1234) { Ok(process) => { match process.stat() { Ok(stat) => println!("OK: {}", stat.comm), Err(ProcError::PermissionDenied(_)) => println!("Root required"), Err(ProcError::NotFound(_)) => println!("Process not found"), Err(e) => eprintln!("Error: {}", e), } } Err(e) => eprintln!("Failed to create process: {}", e), } ``` -------------------------------- ### Detect Kernel Version and Check Features Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Detect the current kernel version and conditionally enable features based on version checks. Handles optional fields for compatibility. ```rust use procfs::KernelVersion; let kernel = KernelVersion::current()?; if kernel >= &KernelVersion::new(4, 20, 0) { // PSI metrics available let psi = procfs::MemoryPressure::current()?; } if kernel >= &KernelVersion::new(5, 0, 0) { // Additional fields available in structs } ``` -------------------------------- ### Process Struct Definition Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Defines the Process structure, holding process ID, root path, and file descriptor. ```rust pub struct Process { pub pid: i32, root: PathBuf, fd: Option, } ``` -------------------------------- ### Определение MMPermissions Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Определяет битовые флаги для прав доступа к областям памяти процесса. ```rust pub struct MMPermissions: u8 { const READ = 1 << 0; const WRITE = 1 << 1; const EXECUTE = 1 << 2; const SHARED = 1 << 3; const PRIVATE = 1 << 4; } ``` -------------------------------- ### Calculate CPU Percentage for a Process Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Calculates the CPU percentage utilized by a specific process over a given interval. Requires the process ID and a duration for measurement. ```Rust use procfs::process::Process; use std::time::Duration; use std::thread; fn cpu_percentage(pid: i32, interval: Duration) -> procfs::ProcResult { let process = Process::new(pid)?; let tps = procfs::ticks_per_second() as f64; let stat1 = process.stat()?; let time1 = (stat1.utime + stat1.stime) as f64; thread::sleep(interval); let stat2 = process.stat()?; let time2 = (stat2.utime + stat2.stime) as f64; let cpu_seconds = (time2 - time1) / tps; Ok((cpu_seconds / interval.as_secs_f64()) * 100.0) } ``` -------------------------------- ### Monitor All Processes Source: https://github.com/eminence/procfs/blob/master/_autodocs/README.md Iterates through all running processes, printing their PID and command name if available. Handles potential errors during process stat retrieval. ```rust use procfs::process; for proc_result in process::all_processes()? { match proc_result { Ok(process) => { if let Ok(stat) = process.stat() { println!("{}: {}", stat.pid, stat.comm); } } Err(e) => eprintln!("Error: {}", e), } } ``` -------------------------------- ### Определение VmFlags Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Определяет битовые флаги для различных свойств областей виртуальной памяти. ```rust pub struct VmFlags: u32 { const RD = 1 << 0; // Readable const WR = 1 << 1; // Writable const EX = 1 << 2; // Executable const SH = 1 << 3; // Shared const MR = 1 << 4; // May read const MW = 1 << 5; // May write const ME = 1 << 6; // May execute const MS = 1 << 7; // May share const GD = 1 << 8; // Grows down const PF = 1 << 9; // Pure PFN range // ... и много других флагов } ``` -------------------------------- ### diskstats() Source: https://github.com/eminence/procfs/blob/master/_autodocs/6-disk-and-network.md Retrieves disk I/O statistics for all disks from the /proc/diskstats file. It returns a `ProcResult` containing a vector of `DiskStat` structs. ```APIDOC ## diskstats() ### Description Retrieves statistics for all disks from `/proc/diskstats`. ### Method ```rust pub fn diskstats() -> ProcResult> ``` ### Parameters None ### Response - `ProcResult>`: A result containing a vector of `DiskStat` structs on success, or an error. ### Request Example ```rust let diskstats = procfs::diskstats()?; for disk in diskstats { let throughput_read = disk.sectors_read as f64 * 512.0 / disk.time_reading.max(1) as f64; let throughput_write = disk.sectors_written as f64 * 512.0 / disk.time_writing.max(1) as f64; println!("{}: read={:.2} MB/s, write={:.2} MB/s", disk.name, throughput_read / 1_000_000.0, throughput_write / 1_000_000.0 ); } ``` ### Response Example ```json [ { "major": 8, "minor": 0, "name": "sda", "reads": 1000, "merged": 500, "sectors_read": 100000, "time_reading": 10000, "writes": 2000, "writes_merged": 1000, "sectors_written": 200000, "time_writing": 20000, "in_progress": 0, "time_in_progress": 500, "weighted_time_in_progress": 1000, "discards": null, "discards_merged": null, "sectors_discarded": null, "time_discarding": null, "flushes": null, "time_flushing": null } ] ``` ``` -------------------------------- ### WithSystemInfo Trait Source: https://github.com/eminence/procfs/blob/master/_autodocs/1-core-types.md The `WithSystemInfo` trait enables types to utilize system information to derive values. It defines an associated `Output` type and a `with_system_info` method. ```APIDOC ## Trait: WithSystemInfo<'a> ### Description Allows a type to use system information to obtain derived values. ### Methods - `with_system_info(self, info: &SystemInfo) -> Self::Output`: Processes the type using the provided `SystemInfo` to produce an output. ### Associated Types - `Output: 'a`: The type produced after processing with system information. ``` -------------------------------- ### Implement FromRead for Custom Data Structure Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Shows how to implement the `FromRead` trait for a custom struct, enabling it to be parsed from a reader. This involves reading data and parsing it into the struct's fields. ```rust use procfs::{FromRead, ProcResult}; use std::io::Read; struct CustomData { field1: String, field2: u64, } impl FromRead for CustomData { fn from_read(mut r: R) -> ProcResult { let mut buf = String::new(); r.read_to_string(&mut buf)?; let mut lines = buf.lines(); let field1 = procfs::expect!(lines.next()).to_string(); let field2 = procfs::expect!(lines.next()).parse()?; Ok(CustomData { field1, field2 }) } } ``` -------------------------------- ### PressureRecord Struct Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Holds system pressure metrics, including average pressure over different time windows and total delay. Available on Linux 4.20+ and requires CONFIG_PSI. ```rust pub struct PressureRecord { pub avg10: f32, pub avg60: f32, pub avg300: f32, pub total: u64, } ``` -------------------------------- ### Определение CoredumpFlags Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Определяет битовые флаги для управления включением различных частей памяти в core dump. ```rust pub struct CoredumpFlags: u32 { const ANONYMOUS_PRIVATE_MAPPINGS = 0x01; const ANONYMOUS_SHARED_MAPPINGS = 0x02; const FILEBACKED_PRIVATE_MAPPINGS = 0x04; const FILEBACKED_SHARED_MAPPINGS = 0x08; const ELF_HEADERS = 0x10; const PROVATE_HUGEPAGES = 0x20; const SHARED_HUGEPAGES = 0x40; const PRIVATE_DAX_PAGES = 0x80; const SHARED_DAX_PAGES = 0x100; } ``` -------------------------------- ### Repeated Reads with Caching Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Utilize global caching for kernel version detection to avoid redundant reads on repeated calls. ```rust let kernel_version = procfs::KernelVersion::current()?; // Cached globally // Subsequent calls return cached value ``` -------------------------------- ### Пример использования MMPermissions Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Демонстрирует парсинг строки прав доступа и проверку наличия флагов. ```rust use std::str::FromStr; use procfs::process::MMPermissions; let perms = MMPermissions::from_str("rwxp").unwrap(); if perms.contains(MMPermissions::READ) { println!("Readable"); } let perm_str = perms.as_str(); // "rwxp" ``` -------------------------------- ### WithCurrentSystemInfo Trait Definition Source: https://github.com/eminence/procfs/blob/master/_autodocs/1-core-types.md A specialized version of WithSystemInfo that uses the current system information available within the procfs crate. It simplifies accessing derived values. ```rust pub trait WithCurrentSystemInfo<'a>: WithSystemInfo<'a> + Sized { fn get(self) -> Self::Output; } ``` -------------------------------- ### Monitor Kernel Stats Changes Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Monitor changes in kernel statistics by taking snapshots at different times and comparing them. Useful for performance tracking. ```rust use std::thread; use std::time::Duration; let stat1 = procfs::KernelStats::current()?; thread::sleep(Duration::from_secs(1)); let stat2 = procfs::KernelStats::current()?; // Compare stat1 and stat2 ``` -------------------------------- ### Send and Sync Compliance for Procfs Types Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md All public types in the procfs crate implement the `Send` and `Sync` traits, allowing them to be safely shared across threads. ```rust use std::sync::Arc; use procfs::process::Process; fn requires_send(_: T) {} fn requires_sync(_: T) {} let proc = Process::myself().unwrap(); requires_send(proc); // OK requires_sync(proc); // OK let shared = Arc::new(proc); // Can share across threads ``` -------------------------------- ### Handle Process Enumeration Race Conditions Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Iterate through all processes while accounting for potential race conditions where processes may be created or destroyed during iteration. Skips processes that have exited. ```rust // May miss processes created during iteration for proc_result in procfs::process::all_processes()? { // Process may have exited here if let Ok(process) = proc_result { if let Err(procfs::ProcError::NotFound(_)) = process.stat() { // Process exited, skip it } } } ``` -------------------------------- ### Enable Backtrace Feature for Debugging Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Enable the 'backtrace' feature in Cargo.toml to capture and print backtraces for internal errors. Access the backtrace via the `ProcError::InternalError` variant. ```toml [dependencies] procfs = { version = "0.18", features = ["backtrace"] } ``` ```rust use procfs::ProcError; match procfs::Meminfo::current() { Err(ProcError::InternalError(e)) => { #[cfg(feature = "backtrace")] println!("Backtrace: {:?}", e.backtrace); eprintln!("Internal error at {}:{}", e.file, e.line); } _ => {} } ``` -------------------------------- ### VmFlags (bitflags) Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Flags that define the properties of virtual memory regions, used in `/proc//maps`. ```APIDOC ## VmFlags (bitflags) ### Description Flags that define the properties of virtual memory regions, used in `/proc//maps`. ### Constants - `RD` (1 << 0): Readable. - `WR` (1 << 1): Writable. - `EX` (1 << 2): Executable. - `SH` (1 << 3): Shared. - `MR` (1 << 4): May read. - `MW` (1 << 5): May write. - `ME` (1 << 6): May execute. - `MS` (1 << 7): May share. - `GD` (1 << 8): Grows down. - `PF` (1 << 9): Pure PFN range. - ... and many other flags. ``` -------------------------------- ### Zero-Copy Memory Access in Procfs Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Methods in procfs return references to avoid unnecessary allocations. Iterators parse process information lazily on demand. ```rust let cpuinfo = procfs::CpuInfo::current()?; let model: Option<&str> = cpuinfo.model_name(0); // &str, not String ``` ```rust for proc in procfs::process::all_processes()? { // Process is parsed lazily } ``` -------------------------------- ### One-Time Read of Meminfo Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Perform a single read of the system's memory information. This is suitable for infrequent checks. ```rust let meminfo = procfs::Meminfo::current()?; // Reads from disk once ``` -------------------------------- ### Parse Stat Data with Explicit System Info Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Parse stat data manually by providing explicit system information. This is useful when procfs-core is used without the procfs wrapper. ```rust use procfs_core::{FromReadSI, ExplicitSystemInfo, process::Stat}; use std::io::Cursor; // Parse stat data with explicit system info let stat_data = b"1 (init) S 0 1 1 0 -1 4194304 123 456..."; let stat = Stat::from_read( Cursor::new(stat_data), &ExplicitSystemInfo { boot_time_secs: 1692972606, ticks_per_second: 100, page_size: 4096, is_little_endian: true, } )?; ``` -------------------------------- ### Track Process Memory Changes Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Defines a structure to hold virtual memory size (vmsize) and resident set size (vmrss) for a process. Provides a method to calculate the difference between two memory states. ```Rust struct ProcessMemory { vmsize: u64, vmrss: u64, } impl ProcessMemory { fn delta(&self, other: &ProcessMemory) -> (i64, i64) { ( other.vmsize as i64 - self.vmsize as i64, other.vmrss as i64 - self.vmrss as i64, ) } } ``` -------------------------------- ### Stat::flags() Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Converts the 'flags' field into a set of bit flags, providing information about process attributes. ```APIDOC ## flags() ### Description Converts the `flags` field into a set of bit flags. ### Method `flags(&self) -> StatFlags` ### Return Value `StatFlags` - A set of bit flags representing process attributes. ### Example ```rust let stat = process.stat()?; let flags = stat.flags(); if flags.contains(procfs::process::StatFlags::PF_KTHREAD) { println!("This is a kernel thread"); } ``` ``` -------------------------------- ### Пример использования MMapPath Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Итерирует по областям памяти процесса и обрабатывает различные типы путей или назначений. ```rust let maps = process.maps()?; for map in maps { match &map.pathname { procfs::process::MMapPath::Path(p) => println!("File: {}", p.display()), procfs::process::MMapPath::Heap => println!("Heap region"), procfs::process::MMapPath::Stack => println!("Main stack"), procfs::process::MMapPath::TStack(tid) => println!("Thread {} stack", tid), _ => println!("Other: {:?}", map.pathname), } } ``` -------------------------------- ### Setting Rust Version in Cargo.toml Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Specify the minimum supported Rust version (MSRV) in your Cargo.toml file. This ensures compatibility with the required Rust toolchain. ```toml [package] rust-version = "1.70" ``` -------------------------------- ### DiskStat Structure Definition Source: https://github.com/eminence/procfs/blob/master/_autodocs/6-disk-and-network.md Defines the structure for holding disk I/O statistics. This structure mirrors the fields found in the /proc/diskstats file. ```rust pub struct DiskStat { pub major: i32, pub minor: i32, pub name: String, pub reads: u64, pub merged: u64, pub sectors_read: u64, pub time_reading: u64, pub writes: u64, pub writes_merged: u64, pub sectors_written: u64, pub time_writing: u64, pub in_progress: u64, pub time_in_progress: u64, pub weighted_time_in_progress: u64, pub discards: Option, pub discards_merged: Option, pub sectors_discarded: Option, pub time_discarding: Option, pub flushes: Option, pub time_flushing: Option, } ``` -------------------------------- ### Prevent Race Conditions in Process Enumeration Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Addresses race conditions where a process might exit during enumeration. Shows the robust approach of handling `NotFound` errors when accessing process information. ```Rust // WRONG: Process might exit between lines for proc in procfs::process::all_processes()? { let pid = proc.pid; let maps = proc.maps()?; // Might fail if process exited } // RIGHT for proc_result in procfs::process::all_processes()? { match proc_result { Ok(proc) => { match proc.maps() { Ok(maps) => { /* use maps */ }, Err(procfs::ProcError::NotFound(_)) => { // Process exited, skip } Err(e) => eprintln!("Error: {}", e), } } Err(e) => eprintln!("Error: {}", e), } } ``` -------------------------------- ### Convert RSS pages to bytes Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Converts the Resident Set Size (RSS) from pages to bytes. This method is useful for accurately reporting memory usage in bytes. ```rust pub fn rss_bytes(&self) -> impl WithSystemInfo<'a, Output = u64> ``` ```rust use procfs::WithCurrentSystemInfo; let stat = process.stat()?; let rss_bytes = stat.rss_bytes().get(); println!("RSS: {} bytes", rss_bytes); ``` -------------------------------- ### MMPermissions (bitflags) Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Represents the access permissions for process memory regions. It is a bitflag enum that can be combined to specify read, write, execute, shared, or private access. ```APIDOC ## MMPermissions (bitflags) ### Description Represents the access permissions for process memory regions. It is a bitflag enum that can be combined to specify read, write, execute, shared, or private access. ### Constants - `READ` (1 << 0): Read permission is allowed. - `WRITE` (1 << 1): Write permission is allowed. - `EXECUTE` (1 << 2): Execute permission is allowed. - `SHARED` (1 << 3): Memory is shared (mutually exclusive with PRIVATE). - `PRIVATE` (1 << 4): Memory is private, copy-on-write. ### Methods - `as_str()`: Returns a string representation of the permissions (e.g., "rwxp"). - `FromStr::from_str(s)`: Parses a string representation of permissions (e.g., "rwxp"). ### Example ```rust use std::str::FromStr; use procfs::process::MMPermissions; let perms = MMPermissions::from_str("rwxp").unwrap(); if perms.contains(MMPermissions::READ) { println!("Readable"); } let perm_str = perms.as_str(); // "rwxp" ``` ``` -------------------------------- ### Constructing Non-Exhaustive Structs in Rust Source: https://github.com/eminence/procfs/blob/master/_autodocs/8-advanced-topics.md Use constructors or the Current trait to instantiate structs marked with #[non_exhaustive]. Direct construction is not allowed, ensuring compatibility when new fields are added. ```rust let m = procfs::Meminfo::current()?; let m2: procfs::Meminfo = procfs::Current::current()?; ``` -------------------------------- ### Stat::rss_bytes() Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Converts the Resident Set Size (RSS) from pages to bytes. ```APIDOC ## rss_bytes() ### Description Converts the RSS (in pages) to bytes. ### Method `rss_bytes(&self) -> impl WithSystemInfo<'a, Output = u64>` ### Return Value `impl WithSystemInfo<'a, Output = u64>` - An object that can provide the RSS in bytes. ### Example ```rust use procfs::WithCurrentSystemInfo; let stat = process.stat()?; let rss_bytes = stat.rss_bytes().get(); println!("RSS: {} bytes", rss_bytes); ``` ``` -------------------------------- ### Stat::state() Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Converts the 'state' field (char) into a ProcState enum, representing the process's current execution state. ```APIDOC ## state() ### Description Converts the `state` field (char) into a `ProcState` enum. ### Method `state(&self) -> ProcState` ### Return Value `ProcState` - The current execution state of the process. ### Possible Values | Value | Description | |---------|---------------------------------| | `Running` | Executing (R) | | `Sleeping`| Sleeping in interruptible wait (S)| | `Waiting` | Waiting for disk I/O (D) | | `Zombie` | Zombie (Z) | | `Stopped` | Stopped (T) | | `Tracing` | Traced (t) | | `Dead` | Dead (X) | ### Example ```rust let stat = process.stat()?; match stat.state() { procfs::process::ProcState::Running => println!("Process is running"), procfs::process::ProcState::Sleeping => println!("Process is sleeping"), _ => println!("Other state"), } ``` ``` -------------------------------- ### Limit Struct Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Defines soft and hard limits for system resources. The soft limit can be exceeded up to the hard limit. ```rust pub struct Limit { pub soft: u64, pub hard: u64, } ``` ```rust let limits = process.limits()?; println!("Max open files: soft={}, hard={}", limits.max_open_files.soft, limits.max_open_files.hard); ``` -------------------------------- ### Stat Struct Definition Source: https://github.com/eminence/procfs/blob/master/_autodocs/3-process-module.md Defines the structure for process statistics, including PID, command, state, and various performance counters. ```rust pub struct Stat { pub pid: i32, pub comm: String, pub state: char, pub ppid: i32, pub pgrp: i32, pub session: i32, pub tty_nr: i32, pub tpgid: i32, pub flags: u32, pub minflt: u64, pub cminflt: u64, pub majflt: u64, pub cmajflt: u64, pub utime: u64, pub stime: u64, pub cutime: i64, pub cstime: i64, pub priority: i64, pub nice: i64, pub num_threads: i64, pub itrealvalue: i64, pub starttime: u64, pub vsize: u64, pub rss: u64, // ... и другие поля } ``` -------------------------------- ### MMapPath (enum) Source: https://github.com/eminence/procfs/blob/master/_autodocs/5-types-reference.md Represents the path or designation of a memory-mapped region. ```APIDOC ## MMapPath (enum) ### Description Represents the path or designation of a memory-mapped region. ### Variants - `Path(PathBuf)`: Represents a file path. - `Heap`: Represents the process heap. - `Stack`: Represents the main thread's stack. - `TStack(u32)`: Represents a thread's stack, identified by its TID. - `Vdso`: Represents a virtual dynamically linked object. - `Vsyscall`: Represents a virtual system call. - `Vvar`: Represents variables for a reduced system call. - `Anon`: Represents an anonymous memory region (Linux 5.17+). - `Other(String)`: Represents an unknown memory region designation. ### Example ```rust let maps = process.maps()?; for map in maps { match &map.pathname { procfs::process::MMapPath::Path(p) => println!("File: {}", p.display()), procfs::process::MMapPath::Heap => println!("Heap region"), procfs::process::MMapPath::Stack => println!("Main stack"), procfs::process::MMapPath::TStack(tid) => println!("Thread {} stack", tid), _ => println!("Other: {:?}", map.pathname), } } ``` ``` -------------------------------- ### WithSystemInfo Trait Definition Source: https://github.com/eminence/procfs/blob/master/_autodocs/1-core-types.md Enables types to utilize system information for deriving values. This trait is designed for transformations that depend on system-wide context. ```rust pub trait WithSystemInfo<'a>: 'a { type Output: 'a; fn with_system_info(self, info: &SystemInfo) -> Self::Output; } ```