mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
Merge pull request #7892 from cakebaker/uptime_refactor_uumain
uptime: refactor `uumain`
This commit is contained in:
commit
45b0c39ed7
2 changed files with 47 additions and 65 deletions
|
@ -6,7 +6,8 @@
|
|||
// spell-checker:ignore getloadavg behaviour loadavg uptime upsecs updays upmins uphours boottime nusers utmpxname gettime clockid
|
||||
|
||||
use chrono::{Local, TimeZone, Utc};
|
||||
use clap::ArgMatches;
|
||||
#[cfg(unix)]
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
use thiserror::Error;
|
||||
use uucore::error::{UError, UResult};
|
||||
|
@ -44,14 +45,10 @@ pub enum UptimeError {
|
|||
// io::Error wrapper
|
||||
#[error("couldn't get boot time: {0}")]
|
||||
IoErr(#[from] io::Error),
|
||||
|
||||
#[error("couldn't get boot time: Is a directory")]
|
||||
TargetIsDir,
|
||||
|
||||
#[error("couldn't get boot time: Illegal seek")]
|
||||
TargetIsFifo,
|
||||
#[error("extra operand '{0}'")]
|
||||
ExtraOperandError(String),
|
||||
}
|
||||
|
||||
impl UError for UptimeError {
|
||||
|
@ -64,41 +61,22 @@ impl UError for UptimeError {
|
|||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches = uu_app().try_get_matches_from(args)?;
|
||||
|
||||
#[cfg(windows)]
|
||||
return default_uptime(&matches);
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::ffi::OsString;
|
||||
use uucore::error::set_exit_code;
|
||||
use uucore::show_error;
|
||||
let file_path = matches.get_one::<OsString>(options::PATH);
|
||||
#[cfg(windows)]
|
||||
let file_path = None;
|
||||
|
||||
let argument = matches.get_many::<OsString>(options::PATH);
|
||||
|
||||
// Switches to default uptime behaviour if there is no argument
|
||||
if argument.is_none() {
|
||||
return default_uptime(&matches);
|
||||
}
|
||||
let mut arg_iter = argument.unwrap();
|
||||
|
||||
let file_path = arg_iter.next().unwrap();
|
||||
if let Some(path) = arg_iter.next() {
|
||||
// Uptime doesn't attempt to calculate boot time if there is extra arguments.
|
||||
// Its a fatal error
|
||||
show_error!(
|
||||
"{}",
|
||||
UptimeError::ExtraOperandError(path.to_owned().into_string().unwrap())
|
||||
);
|
||||
set_exit_code(1);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
uptime_with_file(file_path)
|
||||
if matches.get_flag(options::SINCE) {
|
||||
uptime_since()
|
||||
} else if let Some(path) = file_path {
|
||||
uptime_with_file(path)
|
||||
} else {
|
||||
default_uptime()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(uucore::util_name())
|
||||
let cmd = Command::new(uucore::util_name())
|
||||
.version(uucore::crate_version!())
|
||||
.about(ABOUT)
|
||||
.override_usage(format_usage(USAGE))
|
||||
|
@ -109,18 +87,20 @@ pub fn uu_app() -> Command {
|
|||
.long(options::SINCE)
|
||||
.help("system up since")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::PATH)
|
||||
.help("file to search boot time from")
|
||||
.action(ArgAction::Append)
|
||||
.value_parser(ValueParser::os_string())
|
||||
.value_hint(ValueHint::AnyPath),
|
||||
)
|
||||
);
|
||||
#[cfg(unix)]
|
||||
cmd.arg(
|
||||
Arg::new(options::PATH)
|
||||
.help("file to search boot time from")
|
||||
.action(ArgAction::Set)
|
||||
.num_args(0..=1)
|
||||
.value_parser(ValueParser::os_string())
|
||||
.value_hint(ValueHint::AnyPath),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn uptime_with_file(file_path: &std::ffi::OsString) -> UResult<()> {
|
||||
fn uptime_with_file(file_path: &OsString) -> UResult<()> {
|
||||
use std::fs;
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
use uucore::error::set_exit_code;
|
||||
|
@ -212,27 +192,29 @@ fn uptime_with_file(file_path: &std::ffi::OsString) -> UResult<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn uptime_since() -> UResult<()> {
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
let (boot_time, _) = process_utmpx(None);
|
||||
|
||||
#[cfg(target_os = "openbsd")]
|
||||
let uptime = get_uptime(None)?;
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
let uptime = get_uptime(boot_time)?;
|
||||
#[cfg(target_os = "windows")]
|
||||
let uptime = get_uptime(None)?;
|
||||
|
||||
let initial_date = Local
|
||||
.timestamp_opt(Utc::now().timestamp() - uptime, 0)
|
||||
.unwrap();
|
||||
println!("{}", initial_date.format("%Y-%m-%d %H:%M:%S"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Default uptime behaviour i.e. when no file argument is given.
|
||||
fn default_uptime(matches: &ArgMatches) -> UResult<()> {
|
||||
if matches.get_flag(options::SINCE) {
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
let (boot_time, _) = process_utmpx(None);
|
||||
|
||||
#[cfg(target_os = "openbsd")]
|
||||
let uptime = get_uptime(None)?;
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
let uptime = get_uptime(boot_time)?;
|
||||
#[cfg(target_os = "windows")]
|
||||
let uptime = get_uptime(None)?;
|
||||
let initial_date = Local
|
||||
.timestamp_opt(Utc::now().timestamp() - uptime, 0)
|
||||
.unwrap();
|
||||
println!("{}", initial_date.format("%Y-%m-%d %H:%M:%S"));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn default_uptime() -> UResult<()> {
|
||||
print_time();
|
||||
print_uptime(None)?;
|
||||
print_nusers(None);
|
||||
|
@ -251,7 +233,7 @@ fn print_loadavg() {
|
|||
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
fn process_utmpx(file: Option<&std::ffi::OsString>) -> (Option<time_t>, usize) {
|
||||
fn process_utmpx(file: Option<&OsString>) -> (Option<time_t>, usize) {
|
||||
let mut nusers = 0;
|
||||
let mut boot_time = None;
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ fn test_uptime_with_extra_argument() {
|
|||
.arg("a")
|
||||
.arg("b")
|
||||
.fails()
|
||||
.stderr_contains("extra operand 'b'");
|
||||
.stderr_contains("unexpected value 'b'");
|
||||
}
|
||||
/// Checks whether uptime displays the correct stderr msg when its called with a directory
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue