mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 17:58:06 +00:00
feature(uptime): add option --since
For this, I: * moved from getops to clap * remove the millisecond maths
This commit is contained in:
parent
8e886c30dc
commit
719f2bf8ae
4 changed files with 55 additions and 37 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1896,6 +1896,8 @@ dependencies = [
|
|||
name = "uptime"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uucore 0.0.2 (git+https://github.com/uutils/uucore/?tag=0.0.2)",
|
||||
|
|
|
@ -12,6 +12,8 @@ path = "src/uptime.rs"
|
|||
[dependencies]
|
||||
getopts = "0.2.18"
|
||||
time = "0.1.40"
|
||||
chrono = "0.4"
|
||||
clap = "2.32"
|
||||
uucore = { version = "0.0.2", features = ["utmpx"] }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -12,19 +12,24 @@
|
|||
|
||||
/* last synced with: cat (GNU coreutils) 8.13 */
|
||||
|
||||
extern crate getopts;
|
||||
extern crate chrono;
|
||||
extern crate clap;
|
||||
extern crate time;
|
||||
|
||||
use chrono::{Local, TimeZone, Utc};
|
||||
use clap::{App, Arg};
|
||||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
// import crate time from utmpx
|
||||
pub use uucore::libc;
|
||||
use uucore::libc::time_t;
|
||||
|
||||
use getopts::Options;
|
||||
|
||||
static NAME: &str = "uptime";
|
||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
static ABOUT: &str = "Print the current time, the length of time the system has been up,\n\
|
||||
the number of users on the system, and the average number of jobs\n\
|
||||
in the run queue over the last 1, 5 and 15 minutes.";
|
||||
static OPT_SINCE: &str = "SINCE";
|
||||
|
||||
#[cfg(unix)]
|
||||
use libc::getloadavg;
|
||||
|
@ -34,38 +39,24 @@ extern "C" {
|
|||
fn GetTickCount() -> libc::uint32_t;
|
||||
}
|
||||
|
||||
fn get_usage() -> String {
|
||||
format!("{0} [OPTION]...", executable!())
|
||||
}
|
||||
|
||||
pub fn uumain(args: Vec<String>) -> i32 {
|
||||
let mut opts = Options::new();
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
.version(VERSION)
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_SINCE)
|
||||
.short("s")
|
||||
.long("since")
|
||||
.help("system up since"),
|
||||
)
|
||||
.get_matches_from(&args);
|
||||
|
||||
opts.optflag("v", "version", "output version information and exit");
|
||||
opts.optflag("h", "help", "display this help and exit");
|
||||
|
||||
let matches = match opts.parse(&args[1..]) {
|
||||
Ok(m) => m,
|
||||
Err(f) => crash!(1, "Invalid options\n{}", f),
|
||||
};
|
||||
if matches.opt_present("version") {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
return 0;
|
||||
}
|
||||
if matches.opt_present("help") || !matches.free.is_empty() {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
println!();
|
||||
println!("Usage:");
|
||||
println!(" {0} [OPTION]", NAME);
|
||||
println!();
|
||||
println!(
|
||||
"{}",
|
||||
opts.usage(
|
||||
"Print the current time, the length of time the system has been up,\n\
|
||||
the number of users on the system, and the average number of jobs\n\
|
||||
in the run queue over the last 1, 5 and 15 minutes."
|
||||
)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
print_time();
|
||||
let (boot_time, user_count) = process_utmpx();
|
||||
let uptime = get_uptime(boot_time);
|
||||
if uptime < 0 {
|
||||
|
@ -73,7 +64,14 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
|
||||
1
|
||||
} else {
|
||||
let upsecs = uptime / 100;
|
||||
if matches.is_present(OPT_SINCE) {
|
||||
let initial_date = Local.timestamp(Utc::now().timestamp() - uptime, 0);
|
||||
println!("{}", initial_date.format("%Y-%m-%d %H:%M:%S"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
print_time();
|
||||
let upsecs = uptime;
|
||||
print_uptime(upsecs);
|
||||
print_nusers(user_count);
|
||||
print_loadavg();
|
||||
|
@ -164,7 +162,7 @@ fn get_uptime(boot_time: Option<time_t>) -> i64 {
|
|||
.ok()
|
||||
.and_then(|mut f| f.read_to_string(&mut proc_uptime).ok())
|
||||
.and_then(|_| proc_uptime.split_whitespace().next())
|
||||
.and_then(|s| s.replace(".", "").parse().ok())
|
||||
.and_then(|s| s.split('.').next().unwrap_or("0").parse().ok())
|
||||
{
|
||||
n
|
||||
} else {
|
||||
|
@ -172,7 +170,7 @@ fn get_uptime(boot_time: Option<time_t>) -> i64 {
|
|||
Some(t) => {
|
||||
let now = time::get_time().sec;
|
||||
let boottime = t as i64;
|
||||
(now - boottime) * 100
|
||||
(now - boottime)
|
||||
}
|
||||
_ => -1,
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
extern crate regex;
|
||||
use self::regex::Regex;
|
||||
use common::util::*;
|
||||
|
||||
#[test]
|
||||
|
@ -12,3 +14,17 @@ fn test_uptime() {
|
|||
assert!(result.stdout.contains(" up "));
|
||||
// Don't check for users as it doesn't show in some CI
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uptime_since() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let result = scene.ucmd().arg("--since").succeeds();
|
||||
|
||||
println!("stdout = {}", result.stdout);
|
||||
println!("stderr = {}", result.stderr);
|
||||
|
||||
assert!(result.success);
|
||||
let re = Regex::new(r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}").unwrap();
|
||||
assert!(re.is_match(&result.stdout.trim()));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue