diff --git a/common/utmpx.rs b/common/utmpx.rs index 7d6dc3458..67ca85de8 100644 --- a/common/utmpx.rs +++ b/common/utmpx.rs @@ -1,6 +1,7 @@ #[allow(non_camel_case_types)]; +#[allow(dead_code)]; -pub use self::utmpx::{DEFAULT_FILE,USER_PROCESS,c_utmp}; +pub use self::utmpx::{DEFAULT_FILE,USER_PROCESS,BOOT_TIME,c_utmp}; #[cfg(target_os = "linux")] mod utmpx { use std::libc; diff --git a/uptime/uptime.rs b/uptime/uptime.rs index bf64e030c..19ec4e8f7 100644 --- a/uptime/uptime.rs +++ b/uptime/uptime.rs @@ -19,7 +19,7 @@ extern crate getopts; use std::os; use std::cast::transmute; use std::io::{print,File}; -use std::libc::{time_t,c_double,c_int,size_t,c_char}; +use std::libc::{time_t,c_double,c_int,c_char}; use std::ptr::null; use std::from_str::from_str; use c_types::c_tm; @@ -72,8 +72,10 @@ fn main() { } print_time(); - print_uptime(); - print_nusers(); + let (boot_time, user_count) = process_utmpx(); + let upsecs = get_uptime(boot_time) / 100; + print_uptime(upsecs); + print_nusers(user_count); print_loadavg(); } @@ -87,13 +89,13 @@ fn print_loadavg() { else { print!("load average: ") for n in range(0, loads) { - print!("{}{}", avg[n], if n == loads - 1 { "\n" } + print!("{:.2f}{}", avg[n], if n == loads - 1 { "\n" } else { ", " } ); } } } -fn print_nusers() { +fn process_utmpx() -> (Option, uint) { DEFAULT_FILE.with_c_str(|filename| { unsafe { utmpxname(filename); @@ -101,6 +103,7 @@ fn print_nusers() { }); let mut nusers = 0; + let mut boot_time = None; unsafe { setutxent(); @@ -112,14 +115,25 @@ fn print_nusers() { break; } - if (*line).ut_type == USER_PROCESS { - nusers += 1; + match (*line).ut_type { + USER_PROCESS => nusers += 1, + BOOT_TIME => { + let t = (*line).ut_tv; + if t.tv_sec > 0 { + boot_time = Some(t.tv_sec); + } + }, + _ => continue } } endutxent(); } + (boot_time, nusers) +} + +fn print_nusers(nusers: uint) { if nusers == 1 { print!("1 user, "); } else if nusers > 1 { @@ -127,7 +141,6 @@ fn print_nusers() { } } - fn print_time() { let local_time = unsafe { *localtime(&time(null())) }; @@ -138,25 +151,35 @@ fn print_time() { } } -fn get_uptime() -> int { - let uptime_text = File::open(&Path::new("/proc/uptime")) - .read_to_str().unwrap(); +fn get_uptime(boot_time: Option) -> i64 { + let proc_uptime = File::open(&Path::new("/proc/uptime")) + .read_to_str(); - return match uptime_text.words().next() { + let uptime_text = match proc_uptime { + Ok(s) => s, + _ => return match boot_time { + Some(t) => { + let now = unsafe { time(null()) }; + (now - t) * 100 // Return in ms + }, + _ => -1 + } + }; + + match uptime_text.words().next() { Some(s) => match from_str(s.replace(".","")) { Some(n) => n, None => -1 }, None => -1 - }; + } } -fn print_uptime() { - let uptime = get_uptime() / 100; - let updays = uptime / 86400; - let uphours = (uptime - (updays * 86400)) / 3600; - let upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60; - if updays == 1 { +fn print_uptime(upsecs: i64) { + let updays = upsecs / 86400; + let uphours = (upsecs - (updays * 86400)) / 3600; + let upmins = (upsecs - (updays * 86400) - (uphours * 3600)) / 60; + if updays == 1 { print!("up {:1d} day, {:2d}:{:02d}, ", updays, uphours, upmins); } else if updays > 1 {