mirror of
https://github.com/uutils/coreutils.git
synced 2025-08-25 04:55:08 +00:00
Merge f580003a62
into 59fd744723
This commit is contained in:
commit
2012ec0bb7
4 changed files with 71 additions and 29 deletions
|
@ -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: <https://wiki.musl-libc.org/faq.html#Q:-Why-is-the-utmp/wtmp-functionality-only-implemented-as-stubs?>
|
||||
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.
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
// spell-checker:ignore getloadavg behaviour loadavg uptime upsecs updays upmins uphours boottime nusers utmpxname gettime clockid couldnt
|
||||
|
||||
use chrono::{Local, TimeZone, Utc};
|
||||
#[cfg(unix)]
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
use thiserror::Error;
|
||||
|
@ -15,13 +14,13 @@ 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;
|
||||
|
||||
#[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 {
|
||||
|
@ -83,15 +82,26 @@ 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)]
|
||||
fn uptime_with_file(_: &OsString) -> UResult<()> {
|
||||
unreachable!("The function should never be called on Windows")
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
|
@ -153,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 {
|
||||
|
@ -167,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 {
|
||||
|
@ -189,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
|
||||
|
@ -224,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<time_t>, usize) {
|
||||
let mut nusers = 0;
|
||||
let mut boot_time = None;
|
||||
|
|
|
@ -79,6 +79,12 @@ pub fn get_uptime(_boot_time: Option<time_t>) -> UResult<i64> {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO implement functionality
|
||||
#[cfg(any(target_os = "android", target_os = "redox"))]
|
||||
pub fn get_uptime(_boot_time: Option<time_t>) -> UResult<i64> {
|
||||
Err(UptimeError::SystemUptime)?
|
||||
}
|
||||
|
||||
/// Get the system uptime
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -89,7 +95,7 @@ pub fn get_uptime(_boot_time: Option<time_t>) -> UResult<i64> {
|
|||
///
|
||||
/// 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<time_t>) -> UResult<i64> {
|
||||
use crate::utmpx::Utmpx;
|
||||
use libc::BOOT_TIME;
|
||||
|
@ -189,7 +195,7 @@ pub fn get_formatted_uptime(boot_time: Option<time_t>) -> UResult<String> {
|
|||
///
|
||||
/// 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.
|
||||
///
|
||||
|
|
|
@ -6,10 +6,9 @@
|
|||
// 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};
|
||||
use uutests::new_ucmd;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
|
@ -20,17 +19,21 @@ 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
|
||||
}
|
||||
|
||||
/// 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() {
|
||||
|
@ -48,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!());
|
||||
|
@ -74,7 +78,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 +92,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 +239,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 +247,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!();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue