From 35fdf43009eaf1b5db5f28f611273984bf48a8b8 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 2 Feb 2025 15:03:45 +0100 Subject: [PATCH 1/7] uptime: move to feat_common_core in Cargo.toml from feat_require_unix_utmpx --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index db8329aa5..14f73c6f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -131,6 +131,7 @@ feat_common_core = [ "unexpand", "uniq", "unlink", + "uptime", "vdir", "wc", "yes", @@ -209,7 +210,7 @@ feat_require_unix = [ ] # "feat_require_unix_utmpx" == set of utilities requiring unix utmp/utmpx support # * ref: -feat_require_unix_utmpx = ["pinky", "uptime", "users", "who"] +feat_require_unix_utmpx = ["pinky", "users", "who"] # "feat_require_unix_hostid" == set of utilities requiring gethostid in libc (only some unixes provide) feat_require_unix_hostid = ["hostid"] # "feat_require_selinux" == set of utilities depending on SELinux. From b631e301c7044465fcc080d6f18a90b5be2f2d50 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 21 May 2025 10:20:49 +0200 Subject: [PATCH 2/7] uptime: add dummy uptime_with_file() for Windows to satisfy the compiler --- src/uu/uptime/src/uptime.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/uu/uptime/src/uptime.rs b/src/uu/uptime/src/uptime.rs index 6e028fbd6..ffc3fc727 100644 --- a/src/uu/uptime/src/uptime.rs +++ b/src/uu/uptime/src/uptime.rs @@ -6,7 +6,11 @@ // spell-checker:ignore getloadavg behaviour loadavg uptime upsecs updays upmins uphours boottime nusers utmpxname gettime clockid couldnt use chrono::{Local, TimeZone, Utc}; +<<<<<<< HEAD #[cfg(unix)] +======= +use std::collections::HashMap; +>>>>>>> bafdfff42 (uptime: add dummy uptime_with_file() for Windows) use std::ffi::OsString; use std::io; use thiserror::Error; @@ -94,6 +98,11 @@ pub fn uu_app() -> Command { ) } +#[cfg(windows)] +fn uptime_with_file(_: &OsString) -> UResult<()> { + unreachable!("The function should never be called on Windows") +} + #[cfg(unix)] fn uptime_with_file(file_path: &OsString) -> UResult<()> { use std::fs; From 0fb69c62ec53e85207b9b8f47cd56eb02bd06cdb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 3 Jun 2025 15:28:33 +0200 Subject: [PATCH 3/7] uptime: disable tests on Windows --- tests/by-util/test_uptime.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/by-util/test_uptime.rs b/tests/by-util/test_uptime.rs index e179f64eb..0d7279eda 100644 --- a/tests/by-util/test_uptime.rs +++ b/tests/by-util/test_uptime.rs @@ -6,7 +6,7 @@ // spell-checker:ignore bincode serde utmp runlevel testusr testx #![allow(clippy::cast_possible_wrap, clippy::unreadable_literal)] -#[cfg(not(target_os = "openbsd"))] +#[cfg(not(any(windows, target_os = "openbsd", target_os = "freebsd")))] use uutests::at_and_ucmd; use uutests::util::TestScenario; use uutests::{new_ucmd, util_name}; @@ -30,7 +30,7 @@ fn test_uptime() { /// Checks for files without utmpx records for which boot time cannot be calculated #[test] -#[cfg(not(any(target_os = "openbsd", target_os = "freebsd")))] +#[cfg(not(any(windows, target_os = "openbsd", target_os = "freebsd")))] // Disabled for freebsd, since it doesn't use the utmpxname() sys call to change the default utmpx // file that is accessed using getutxent() fn test_uptime_for_file_without_utmpx_records() { @@ -74,7 +74,7 @@ fn test_uptime_with_fifo() { } #[test] -#[cfg(not(target_os = "freebsd"))] +#[cfg(not(any(windows, target_os = "freebsd")))] fn test_uptime_with_non_existent_file() { // Disabled for freebsd, since it doesn't use the utmpxname() sys call to change the default utmpx // file that is accessed using getutxent() @@ -88,7 +88,7 @@ fn test_uptime_with_non_existent_file() { // TODO create a similar test for macos // This will pass #[test] -#[cfg(not(any(target_os = "openbsd", target_os = "macos")))] +#[cfg(not(any(windows, target_os = "openbsd", target_os = "macos")))] #[cfg(not(target_env = "musl"))] #[cfg_attr( all(target_arch = "aarch64", target_os = "linux"), @@ -235,6 +235,7 @@ fn test_uptime_with_file_containing_valid_boot_time_utmpx_record() { } #[test] +#[cfg(not(windows))] fn test_uptime_with_extra_argument() { new_ucmd!() .arg("a") @@ -242,8 +243,10 @@ fn test_uptime_with_extra_argument() { .fails() .stderr_contains("unexpected value 'b'"); } + /// Checks whether uptime displays the correct stderr msg when its called with a directory #[test] +#[cfg(not(windows))] fn test_uptime_with_dir() { let (at, mut ucmd) = at_and_ucmd!(); From 1c8dbefe7813df2ff7d60c2e29fa432bc639c933 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 5 Jun 2025 14:42:03 +0200 Subject: [PATCH 4/7] uptime: return Command from uu_app() on Windows --- src/uu/uptime/src/uptime.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/uu/uptime/src/uptime.rs b/src/uu/uptime/src/uptime.rs index ffc3fc727..934413852 100644 --- a/src/uu/uptime/src/uptime.rs +++ b/src/uu/uptime/src/uptime.rs @@ -6,11 +6,6 @@ // spell-checker:ignore getloadavg behaviour loadavg uptime upsecs updays upmins uphours boottime nusers utmpxname gettime clockid couldnt use chrono::{Local, TimeZone, Utc}; -<<<<<<< HEAD -#[cfg(unix)] -======= -use std::collections::HashMap; ->>>>>>> bafdfff42 (uptime: add dummy uptime_with_file() for Windows) use std::ffi::OsString; use std::io; use thiserror::Error; @@ -19,7 +14,7 @@ use uucore::libc::time_t; use uucore::translate; use uucore::uptime::*; -use clap::{Arg, ArgAction, Command, ValueHint, builder::ValueParser}; +use clap::{Arg, ArgAction, Command}; use uucore::LocalizedCommand; use uucore::format_usage; @@ -87,15 +82,21 @@ pub fn uu_app() -> Command { .help(translate!("uptime-help-since")) .action(ArgAction::SetTrue), ); + #[cfg(unix)] - cmd.arg( - Arg::new(options::PATH) - .help(translate!("uptime-help-path")) - .action(ArgAction::Set) - .num_args(0..=1) - .value_parser(ValueParser::os_string()) - .value_hint(ValueHint::AnyPath), - ) + let cmd = { + use clap::{ValueHint, builder::ValueParser}; + cmd.arg( + Arg::new(options::PATH) + .help(translate!("uptime-help-path")) + .action(ArgAction::Set) + .num_args(0..=1) + .value_parser(ValueParser::os_string()) + .value_hint(ValueHint::AnyPath), + ) + }; + + cmd } #[cfg(windows)] From cd9ff4f262664698d4d279169e7fe86b77b5ad84 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 5 Jun 2025 16:31:03 +0200 Subject: [PATCH 5/7] uptime: adapt test_uptime() to work on Windows --- tests/by-util/test_uptime.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/by-util/test_uptime.rs b/tests/by-util/test_uptime.rs index 0d7279eda..60228050a 100644 --- a/tests/by-util/test_uptime.rs +++ b/tests/by-util/test_uptime.rs @@ -20,10 +20,14 @@ fn test_invalid_arg() { #[test] fn test_uptime() { - new_ucmd!() - .succeeds() - .stdout_contains("load average:") - .stdout_contains(" up "); + let result = new_ucmd!().succeeds(); + + result.stdout_contains(" up "); + + #[cfg(not(windows))] + result.stdout_contains("load average:"); + #[cfg(windows)] + result.stdout_does_not_contain("load average:"); // Don't check for users as it doesn't show in some CI } From 6991e8f8b75d11fdc018a9034d8d861ade3b52ba Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 30 Jul 2025 11:16:25 +0200 Subject: [PATCH 6/7] uptime: move imports unused on Windows to test --- tests/by-util/test_uptime.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/by-util/test_uptime.rs b/tests/by-util/test_uptime.rs index 60228050a..6cc5fea6a 100644 --- a/tests/by-util/test_uptime.rs +++ b/tests/by-util/test_uptime.rs @@ -8,8 +8,7 @@ #[cfg(not(any(windows, target_os = "openbsd", target_os = "freebsd")))] use uutests::at_and_ucmd; -use uutests::util::TestScenario; -use uutests::{new_ucmd, util_name}; +use uutests::new_ucmd; use regex::Regex; @@ -52,6 +51,7 @@ fn test_uptime_for_file_without_utmpx_records() { #[test] #[cfg(all(unix, feature = "cp"))] fn test_uptime_with_fifo() { + use uutests::{util::TestScenario, util_name}; // This test can go on forever in the CI in some cases, might need aborting // Sometimes writing to the pipe is broken let ts = TestScenario::new(util_name!()); From f580003a6235ae9e567c23187618c565d14270c1 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 6 Jun 2025 14:42:18 +0200 Subject: [PATCH 7/7] uptime: make it compile on Android & Redox --- src/uu/uptime/src/uptime.rs | 17 +++++++++++------ src/uucore/src/lib/features/uptime.rs | 23 +++++++++++++++++++++-- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/uu/uptime/src/uptime.rs b/src/uu/uptime/src/uptime.rs index 934413852..af409b164 100644 --- a/src/uu/uptime/src/uptime.rs +++ b/src/uu/uptime/src/uptime.rs @@ -20,7 +20,7 @@ use uucore::LocalizedCommand; use uucore::format_usage; #[cfg(unix)] -#[cfg(not(target_os = "openbsd"))] +#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "android")))] use uucore::utmpx::*; pub mod options { @@ -163,7 +163,7 @@ fn uptime_with_file(file_path: &OsString) -> UResult<()> { print_time(); let user_count; - #[cfg(not(target_os = "openbsd"))] + #[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "android")))] { let (boot_time, count) = process_utmpx(Some(file_path)); if let Some(time) = boot_time { @@ -177,7 +177,7 @@ fn uptime_with_file(file_path: &OsString) -> UResult<()> { user_count = count; } - #[cfg(target_os = "openbsd")] + #[cfg(any(target_os = "openbsd", target_os = "redox", target_os = "android"))] { let upsecs = get_uptime(None); if upsecs >= 0 { @@ -199,12 +199,17 @@ fn uptime_with_file(file_path: &OsString) -> UResult<()> { fn uptime_since() -> UResult<()> { #[cfg(unix)] - #[cfg(not(target_os = "openbsd"))] + #[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "android")))] let uptime = { let (boot_time, _) = process_utmpx(None); get_uptime(boot_time)? }; - #[cfg(any(windows, target_os = "openbsd"))] + #[cfg(any( + windows, + target_os = "openbsd", + target_os = "redox", + target_os = "android" + ))] let uptime = get_uptime(None)?; let since_date = Local @@ -234,7 +239,7 @@ fn print_loadavg() { } #[cfg(unix)] -#[cfg(not(target_os = "openbsd"))] +#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "android")))] fn process_utmpx(file: Option<&OsString>) -> (Option, usize) { let mut nusers = 0; let mut boot_time = None; diff --git a/src/uucore/src/lib/features/uptime.rs b/src/uucore/src/lib/features/uptime.rs index 38991a923..2b479b392 100644 --- a/src/uucore/src/lib/features/uptime.rs +++ b/src/uucore/src/lib/features/uptime.rs @@ -79,6 +79,12 @@ pub fn get_uptime(_boot_time: Option) -> UResult { } } +// TODO implement functionality +#[cfg(any(target_os = "android", target_os = "redox"))] +pub fn get_uptime(_boot_time: Option) -> UResult { + Err(UptimeError::SystemUptime)? +} + /// Get the system uptime /// /// # Arguments @@ -89,7 +95,7 @@ pub fn get_uptime(_boot_time: Option) -> UResult { /// /// Returns a UResult with the uptime in seconds if successful, otherwise an UptimeError. #[cfg(unix)] -#[cfg(not(target_os = "openbsd"))] +#[cfg(not(any(target_os = "openbsd", target_os = "android", target_os = "redox")))] pub fn get_uptime(boot_time: Option) -> UResult { use crate::utmpx::Utmpx; use libc::BOOT_TIME; @@ -189,7 +195,7 @@ pub fn get_formatted_uptime(boot_time: Option) -> UResult { /// /// Returns the number of users currently logged in if successful, otherwise 0. #[cfg(unix)] -#[cfg(not(target_os = "openbsd"))] +#[cfg(not(any(target_os = "openbsd", target_os = "android", target_os = "redox")))] // see: https://gitlab.com/procps-ng/procps/-/blob/4740a0efa79cade867cfc7b32955fe0f75bf5173/library/uptime.c#L63-L115 pub fn get_nusers() -> usize { use crate::utmpx::Utmpx; @@ -236,6 +242,12 @@ pub fn get_nusers(file: &str) -> usize { nusers } +// TODO implement functionality +#[cfg(any(target_os = "android", target_os = "redox"))] +pub fn get_nusers() -> usize { + 0 +} + /// Get the number of users currently logged in /// /// # Returns @@ -334,6 +346,7 @@ pub fn get_formatted_nusers() -> String { /// Returns a UResult with the load average if successful, otherwise an UptimeError. /// The load average is a tuple of three floating point numbers representing the 1-minute, 5-minute, and 15-minute load averages. #[cfg(unix)] +#[cfg(not(any(target_os = "android", target_os = "redox")))] pub fn get_loadavg() -> UResult<(f64, f64, f64)> { use crate::libc::c_double; use libc::getloadavg; @@ -349,6 +362,12 @@ pub fn get_loadavg() -> UResult<(f64, f64, f64)> { } } +// TODO implement functionality +#[cfg(any(target_os = "android", target_os = "redox"))] +pub fn get_loadavg() -> UResult<(f64, f64, f64)> { + Err(UptimeError::SystemLoadavg)? +} + /// Get the system load average /// Windows does not have an equivalent to the load average on Unix-like systems. ///