From 4b857105c9898a0522b7e86aa21df87e288be4f2 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Tue, 25 Mar 2014 15:59:29 +0000 Subject: [PATCH 1/5] Fix OSX crash for uptime --- uptime/uptime.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/uptime/uptime.rs b/uptime/uptime.rs index bf64e030c..491dde0ec 100644 --- a/uptime/uptime.rs +++ b/uptime/uptime.rs @@ -127,7 +127,6 @@ fn print_nusers() { } } - fn print_time() { let local_time = unsafe { *localtime(&time(null())) }; @@ -139,16 +138,21 @@ fn print_time() { } fn get_uptime() -> int { - let uptime_text = File::open(&Path::new("/proc/uptime")) - .read_to_str().unwrap(); + 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 -1 + }; + + match uptime_text.words().next() { Some(s) => match from_str(s.replace(".","")) { Some(n) => n, None => -1 }, None => -1 - }; + } } fn print_uptime() { @@ -156,7 +160,7 @@ fn print_uptime() { let updays = uptime / 86400; let uphours = (uptime - (updays * 86400)) / 3600; let upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60; - if updays == 1 { + if updays == 1 { print!("up {:1d} day, {:2d}:{:02d}, ", updays, uphours, upmins); } else if updays > 1 { From 4124ce66799465dc3275d6d6d46cda72d1183877 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Tue, 25 Mar 2014 16:01:56 +0000 Subject: [PATCH 2/5] Silence dead code warnings for Constants --- common/utmpx.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/common/utmpx.rs b/common/utmpx.rs index 7d6dc3458..08837158c 100644 --- a/common/utmpx.rs +++ b/common/utmpx.rs @@ -1,4 +1,5 @@ #[allow(non_camel_case_types)]; +#[allow(dead_code)]; pub use self::utmpx::{DEFAULT_FILE,USER_PROCESS,c_utmp}; #[cfg(target_os = "linux")] From f3c4657a944c1d7c6d802a5f2de93295532c9312 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Tue, 25 Mar 2014 16:15:14 +0000 Subject: [PATCH 3/5] Truncate load averages to 2 decimal places --- uptime/uptime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uptime/uptime.rs b/uptime/uptime.rs index 491dde0ec..1a98347ce 100644 --- a/uptime/uptime.rs +++ b/uptime/uptime.rs @@ -87,7 +87,7 @@ 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 { ", " } ); } } From 25ee699756beaabab996aba2c588f4885cadccee Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Tue, 25 Mar 2014 16:16:38 +0000 Subject: [PATCH 4/5] Remove unused import. --- uptime/uptime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uptime/uptime.rs b/uptime/uptime.rs index 1a98347ce..a32715081 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; From cf136e1ff4fa85e92a895ecb8161e2445556247e Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Tue, 25 Mar 2014 17:28:31 +0000 Subject: [PATCH 5/5] Try to read BOOT_TIME from utmpx if /proc/uptime fails. --- common/utmpx.rs | 2 +- uptime/uptime.rs | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/common/utmpx.rs b/common/utmpx.rs index 08837158c..67ca85de8 100644 --- a/common/utmpx.rs +++ b/common/utmpx.rs @@ -1,7 +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 a32715081..19ec4e8f7 100644 --- a/uptime/uptime.rs +++ b/uptime/uptime.rs @@ -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(); } @@ -93,7 +95,7 @@ fn print_loadavg() { } } -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 { @@ -137,13 +151,19 @@ fn print_time() { } } -fn get_uptime() -> int { +fn get_uptime(boot_time: Option) -> i64 { let proc_uptime = File::open(&Path::new("/proc/uptime")) .read_to_str(); let uptime_text = match proc_uptime { Ok(s) => s, - _ => return -1 + _ => return match boot_time { + Some(t) => { + let now = unsafe { time(null()) }; + (now - t) * 100 // Return in ms + }, + _ => -1 + } }; match uptime_text.words().next() { @@ -155,11 +175,10 @@ fn get_uptime() -> int { } } -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; +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); }