mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +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"
|
name = "uptime"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
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)",
|
"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)",
|
"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)",
|
"uucore 0.0.2 (git+https://github.com/uutils/uucore/?tag=0.0.2)",
|
||||||
|
|
|
@ -12,6 +12,8 @@ path = "src/uptime.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
time = "0.1.40"
|
time = "0.1.40"
|
||||||
|
chrono = "0.4"
|
||||||
|
clap = "2.32"
|
||||||
uucore = { version = "0.0.2", features = ["utmpx"] }
|
uucore = { version = "0.0.2", features = ["utmpx"] }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -12,19 +12,24 @@
|
||||||
|
|
||||||
/* last synced with: cat (GNU coreutils) 8.13 */
|
/* last synced with: cat (GNU coreutils) 8.13 */
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate chrono;
|
||||||
|
extern crate clap;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
|
||||||
|
use chrono::{Local, TimeZone, Utc};
|
||||||
|
use clap::{App, Arg};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
// import crate time from utmpx
|
// import crate time from utmpx
|
||||||
pub use uucore::libc;
|
pub use uucore::libc;
|
||||||
use uucore::libc::time_t;
|
use uucore::libc::time_t;
|
||||||
|
|
||||||
use getopts::Options;
|
|
||||||
|
|
||||||
static NAME: &str = "uptime";
|
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
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)]
|
#[cfg(unix)]
|
||||||
use libc::getloadavg;
|
use libc::getloadavg;
|
||||||
|
@ -34,38 +39,24 @@ extern "C" {
|
||||||
fn GetTickCount() -> libc::uint32_t;
|
fn GetTickCount() -> libc::uint32_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_usage() -> String {
|
||||||
|
format!("{0} [OPTION]...", executable!())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn uumain(args: Vec<String>) -> i32 {
|
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 (boot_time, user_count) = process_utmpx();
|
||||||
let uptime = get_uptime(boot_time);
|
let uptime = get_uptime(boot_time);
|
||||||
if uptime < 0 {
|
if uptime < 0 {
|
||||||
|
@ -73,7 +64,14 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
|
|
||||||
1
|
1
|
||||||
} else {
|
} 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_uptime(upsecs);
|
||||||
print_nusers(user_count);
|
print_nusers(user_count);
|
||||||
print_loadavg();
|
print_loadavg();
|
||||||
|
@ -164,7 +162,7 @@ fn get_uptime(boot_time: Option<time_t>) -> i64 {
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|mut f| f.read_to_string(&mut proc_uptime).ok())
|
.and_then(|mut f| f.read_to_string(&mut proc_uptime).ok())
|
||||||
.and_then(|_| proc_uptime.split_whitespace().next())
|
.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
|
n
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,7 +170,7 @@ fn get_uptime(boot_time: Option<time_t>) -> i64 {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
let now = time::get_time().sec;
|
let now = time::get_time().sec;
|
||||||
let boottime = t as i64;
|
let boottime = t as i64;
|
||||||
(now - boottime) * 100
|
(now - boottime)
|
||||||
}
|
}
|
||||||
_ => -1,
|
_ => -1,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
extern crate regex;
|
||||||
|
use self::regex::Regex;
|
||||||
use common::util::*;
|
use common::util::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -12,3 +14,17 @@ fn test_uptime() {
|
||||||
assert!(result.stdout.contains(" up "));
|
assert!(result.stdout.contains(" up "));
|
||||||
// Don't check for users as it doesn't show in some CI
|
// 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…
Add table
Add a link
Reference in a new issue