1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #144 from Ryman/master

Implement uptime for OSX (probably some other unix too)
This commit is contained in:
Arcterus 2014-03-25 13:15:47 -07:00
commit af5401e952
2 changed files with 44 additions and 20 deletions

View file

@ -1,6 +1,7 @@
#[allow(non_camel_case_types)]; #[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")] #[cfg(target_os = "linux")]
mod utmpx { mod utmpx {
use std::libc; use std::libc;

View file

@ -19,7 +19,7 @@ extern crate getopts;
use std::os; use std::os;
use std::cast::transmute; use std::cast::transmute;
use std::io::{print,File}; 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::ptr::null;
use std::from_str::from_str; use std::from_str::from_str;
use c_types::c_tm; use c_types::c_tm;
@ -72,8 +72,10 @@ fn main() {
} }
print_time(); print_time();
print_uptime(); let (boot_time, user_count) = process_utmpx();
print_nusers(); let upsecs = get_uptime(boot_time) / 100;
print_uptime(upsecs);
print_nusers(user_count);
print_loadavg(); print_loadavg();
} }
@ -87,13 +89,13 @@ fn print_loadavg() {
else { else {
print!("load average: ") print!("load average: ")
for n in range(0, loads) { for n in range(0, loads) {
print!("{}{}", avg[n], if n == loads - 1 { "\n" } print!("{:.2f}{}", avg[n], if n == loads - 1 { "\n" }
else { ", " } ); else { ", " } );
} }
} }
} }
fn print_nusers() { fn process_utmpx() -> (Option<time_t>, uint) {
DEFAULT_FILE.with_c_str(|filename| { DEFAULT_FILE.with_c_str(|filename| {
unsafe { unsafe {
utmpxname(filename); utmpxname(filename);
@ -101,6 +103,7 @@ fn print_nusers() {
}); });
let mut nusers = 0; let mut nusers = 0;
let mut boot_time = None;
unsafe { unsafe {
setutxent(); setutxent();
@ -112,14 +115,25 @@ fn print_nusers() {
break; break;
} }
if (*line).ut_type == USER_PROCESS { match (*line).ut_type {
nusers += 1; USER_PROCESS => nusers += 1,
BOOT_TIME => {
let t = (*line).ut_tv;
if t.tv_sec > 0 {
boot_time = Some(t.tv_sec);
}
},
_ => continue
} }
} }
endutxent(); endutxent();
} }
(boot_time, nusers)
}
fn print_nusers(nusers: uint) {
if nusers == 1 { if nusers == 1 {
print!("1 user, "); print!("1 user, ");
} else if nusers > 1 { } else if nusers > 1 {
@ -127,7 +141,6 @@ fn print_nusers() {
} }
} }
fn print_time() { fn print_time() {
let local_time = unsafe { *localtime(&time(null())) }; let local_time = unsafe { *localtime(&time(null())) };
@ -138,25 +151,35 @@ fn print_time() {
} }
} }
fn get_uptime() -> int { fn get_uptime(boot_time: Option<time_t>) -> i64 {
let uptime_text = File::open(&Path::new("/proc/uptime")) let proc_uptime = File::open(&Path::new("/proc/uptime"))
.read_to_str().unwrap(); .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(s) => match from_str(s.replace(".","")) {
Some(n) => n, Some(n) => n,
None => -1 None => -1
}, },
None => -1 None => -1
}; }
} }
fn print_uptime() { fn print_uptime(upsecs: i64) {
let uptime = get_uptime() / 100; let updays = upsecs / 86400;
let updays = uptime / 86400; let uphours = (upsecs - (updays * 86400)) / 3600;
let uphours = (uptime - (updays * 86400)) / 3600; let upmins = (upsecs - (updays * 86400) - (uphours * 3600)) / 60;
let upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60; if updays == 1 {
if updays == 1 {
print!("up {:1d} day, {:2d}:{:02d}, ", updays, uphours, upmins); print!("up {:1d} day, {:2d}:{:02d}, ", updays, uphours, upmins);
} }
else if updays > 1 { else if updays > 1 {