diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index dfb7bd1e1b..ed830c0535 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -157,6 +157,7 @@ enum ContextHandle { ProcRoot, ProcCpuinfo, ProcMeminfo, + ProcUptime, ProcDir { pid: usize, }, @@ -404,6 +405,9 @@ impl ProcScheme { if path == "proc/meminfo" || path == "meminfo" { return Some(ContextHandle::ProcMeminfo); } + if path == "proc/uptime" || path == "uptime" { + return Some(ContextHandle::ProcUptime); + } let mut parts = path.split('/'); let pid = parts.next()?.parse::().ok()?; match (parts.next(), parts.next()) { @@ -943,8 +947,8 @@ impl KernelScheme for ProcScheme { let mut buf = DirentBuf::new(buf, header_size).ok_or(Error::new(EIO))?; match handle.kind { ContextHandle::ProcRoot => { - // First: system files (cpuinfo, meminfo, etc.) - for (idx, name) in ["cpuinfo", "meminfo"].iter().enumerate() { + // First: system files (cpuinfo, meminfo, uptime) + for (idx, name) in ["cpuinfo", "meminfo", "uptime"].iter().enumerate() { buf.entry(DirEntry { inode: 0, next_opaque_id: (idx + 1) as u64, @@ -960,7 +964,7 @@ impl KernelScheme for ProcScheme { pids.push(context_ref.read(token.token()).pid); } pids.sort_unstable(); - let base_idx = 2; // after cpuinfo + meminfo + let base_idx = 3; // after cpuinfo + meminfo + uptime for (idx, pid) in pids.into_iter().enumerate().skip(opaque.saturating_sub(base_idx)) { let name = format!("{}", pid); buf.entry(DirEntry { @@ -1886,6 +1890,12 @@ impl ContextHandle { ); read_from(buf, output.as_bytes(), offset) } + ContextHandle::ProcUptime => { + let uptime_s = crate::time::monotonic(token) as f64 / crate::time::NANOS_PER_SEC as f64; + let idle_s = 0.0f64; // Red Bear has no per-CPU idle tracking + let output = format!("{:.2} {:.2}\n", uptime_s, idle_s); + read_from(buf, output.as_bytes(), offset) + } ContextHandle::ProcStat { pid } => { let context = proc_context(*pid, token).ok_or(Error::new(ESRCH))?; let (pid, comm, state, ppid, priority, utime, stime, pgrp, session, starttime, owner_proc_id, addr_space) = {