Skip to content

Commit f409041

Browse files
Merge pull request #452 from Bluemangoo/feature/w-c
w: implement `--container`
2 parents f6737ff + 2318b27 commit f409041

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

src/uu/w/src/w.rs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// file that was distributed with this source code.
55

66
#[cfg(target_os = "linux")]
7-
use chrono::Datelike;
7+
use chrono::{Datelike, Local};
88
use clap::crate_version;
99
use clap::{Arg, ArgAction, Command};
1010
#[cfg(target_os = "linux")]
@@ -134,7 +134,7 @@ fn format_time(time: String) -> Result<String, chrono::format::ParseError> {
134134
t = t.drain(..time_offset).collect();
135135
}
136136
// If login time day is not current day, format like Sat16, or Fri06
137-
let current_dt = chrono::Local::now().fixed_offset();
137+
let current_dt = Local::now().fixed_offset();
138138
let dt = chrono::DateTime::parse_from_str(&t, "%Y-%m-%d %H:%M:%S%.f %:z")?;
139139

140140
if current_dt.day() == dt.day() {
@@ -182,6 +182,17 @@ fn fetch_user_info() -> Result<Vec<UserInfo>, std::io::Error> {
182182
Ok(user_info_list)
183183
}
184184

185+
#[cfg(target_os = "linux")]
186+
fn get_uptime_container() -> UResult<i64> {
187+
let proc_file = fs::read_to_string("/proc/1/stat")?;
188+
let proc_stat: Vec<&str> = proc_file.split_whitespace().collect();
189+
let start_time_str = proc_stat.get(21).ok_or(UptimeError::SystemUptime)?;
190+
let start_time: i64 = start_time_str
191+
.parse()
192+
.map_err(|_| UptimeError::SystemUptime)?;
193+
Ok(get_uptime(None)? + start_time / get_clock_tick())
194+
}
195+
185196
pub fn format_uptime_procps(up_secs: i64) -> UResult<String> {
186197
if up_secs < 0 {
187198
Err(UptimeError::SystemUptime)?;
@@ -208,9 +219,25 @@ pub fn get_formatted_uptime_procps() -> UResult<String> {
208219
Ok(format!("up {time_str}"))
209220
}
210221

211-
fn print_uptime() {
222+
#[cfg(target_os = "linux")]
223+
#[inline]
224+
fn get_formatted_uptime_container_procps() -> UResult<String> {
225+
let time_str = format_uptime_procps(get_uptime_container()?)?;
226+
Ok(format!("up {time_str}"))
227+
}
228+
229+
#[allow(unused_variables)]
230+
fn print_uptime(from_container: bool) {
212231
print!(" {} ", get_formatted_time());
213-
if let Ok(uptime) = get_formatted_uptime_procps() {
232+
#[cfg(target_os = "linux")]
233+
let uptime = if from_container {
234+
get_formatted_uptime_container_procps()
235+
} else {
236+
get_formatted_uptime_procps()
237+
};
238+
#[cfg(not(target_os = "linux"))]
239+
let uptime = get_formatted_uptime_procps();
240+
if let Ok(uptime) = uptime {
214241
print!("{uptime}, ");
215242
} else {
216243
print!("up ???? days ??:??, ");
@@ -235,11 +262,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
235262
let no_header = matches.get_flag("no-header");
236263
let short = matches.get_flag("short");
237264
let old_style = matches.get_flag("old-style");
265+
let container = matches.get_flag("container");
238266

239267
match fetch_user_info() {
240268
Ok(user_info) => {
241269
if !no_header {
242-
print_uptime();
270+
print_uptime(container);
243271
if short {
244272
println!("{:<9}{:<9}{:<7}{:<}", "USER", "TTY", "IDLE", "WHAT");
245273
} else {
@@ -294,6 +322,13 @@ pub fn uu_app() -> Command {
294322
.help("Print help information")
295323
.action(ArgAction::Help),
296324
)
325+
.arg(
326+
Arg::new("container")
327+
.short('c')
328+
.long("container")
329+
.help("show the container uptime instead of system uptime in the header")
330+
.action(ArgAction::SetTrue),
331+
)
297332
.arg(
298333
Arg::new("no-header")
299334
.short('h')

0 commit comments

Comments
 (0)