diff --git a/src/uu/w/Cargo.toml b/src/uu/w/Cargo.toml index 6be5ccf7..e8f9c239 100644 --- a/src/uu/w/Cargo.toml +++ b/src/uu/w/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["acl", "uutils", "cross-platform", "cli", "utility"] categories = ["command-line-utilities"] [dependencies] -uucore = { workspace = true, features = ["utmpx"] } +uucore = { workspace = true, features = ["utmpx", "uptime"] } clap = { workspace = true } chrono = { workspace = true, default-features = false, features = [ "clock", diff --git a/src/uu/w/src/w.rs b/src/uu/w/src/w.rs index 852b6b0b..bacfe94e 100644 --- a/src/uu/w/src/w.rs +++ b/src/uu/w/src/w.rs @@ -12,6 +12,9 @@ use libc::{sysconf, _SC_CLK_TCK}; #[cfg(target_os = "linux")] use std::{collections::HashMap, fs, path::Path, time::SystemTime}; use std::{process, time::Duration}; +use uucore::uptime::{ + get_formated_uptime, get_formatted_loadavg, get_formatted_nusers, get_formatted_time, +}; #[cfg(target_os = "linux")] use uucore::utmpx::Utmpx; use uucore::{error::UResult, format_usage, help_about, help_usage}; @@ -184,6 +187,21 @@ fn fetch_user_info() -> Result, std::io::Error> { Ok(user_info_list) } +fn print_uptime() { + print!(" {} ", get_formatted_time()); + if let Ok(uptime) = get_formated_uptime(None) { + print!("{}, ", uptime); + } else { + print!("up ???? days ??:??, "); + } + + print!(" {}", get_formatted_nusers()); + if let Ok(loadavg) = get_formatted_loadavg() { + print!(", {}", loadavg); + } + println!(); +} + #[cfg(any(target_os = "macos", target_os = "windows"))] fn fetch_user_info() -> Result, std::io::Error> { Ok(Vec::new()) @@ -200,6 +218,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { match fetch_user_info() { Ok(user_info) => { if !no_header { + print_uptime(); if short { println!("{:<9}{:<9}{:<7}{:<}", "USER", "TTY", "IDLE", "WHAT"); } else { diff --git a/tests/by-util/test_w.rs b/tests/by-util/test_w.rs index 57cd8c21..41bbc760 100644 --- a/tests/by-util/test_w.rs +++ b/tests/by-util/test_w.rs @@ -26,6 +26,10 @@ fn test_no_header() { let result = cmd.stdout_str(); + assert!(match result.lines().next() { + None => true, + Some(line) => !line.contains("user") && !line.contains("load average"), + }); assert!(!result.contains("USER TTY LOGIN@ IDLE JCPU PCPU WHAT")); } } @@ -41,7 +45,7 @@ fn test_option_short() { let cmd_output = cmd.stdout_str(); let cmd_output_lines: Vec<&str> = cmd_output.split('\n').collect(); - let line_output_header = cmd_output_lines[0]; + let line_output_header = cmd_output_lines[1]; let line_output_data_words: Vec<&str> = cmd_output_lines[1] .trim() .split(' ')