From 5274576311e9d783c1887a745cd35f36340a70c7 Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Mon, 13 Oct 2025 10:02:03 -0700 Subject: [PATCH] Include subsecond precision in stat atime/ctime Previously only mtime supported this. Follows on to 1d0dcb596208449bea1f9147e21e85cd95658731. References #3233. References s3fs-fuse/s3fs-fuse#2740. --- src/uu/stat/src/stat.rs | 12 ++++++++++-- tests/by-util/test_stat.rs | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index 85a4bbf55..6498f915a 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -1115,7 +1115,11 @@ impl Stater { // time of last access, human-readable 'x' => OutputType::Str(pretty_time(meta, MetadataTimeField::Access)), // time of last access, seconds since Epoch - 'X' => OutputType::Integer(meta.atime()), + 'X' => { + let (sec, nsec) = metadata_get_time(meta, MetadataTimeField::Access) + .map_or((0, 0), system_time_to_sec); + OutputType::Float(sec as f64 + nsec as f64 / 1_000_000_000.0) + } // time of last data modification, human-readable 'y' => OutputType::Str(pretty_time(meta, MetadataTimeField::Modification)), // time of last data modification, seconds since Epoch @@ -1127,7 +1131,11 @@ impl Stater { // time of last status change, human-readable 'z' => OutputType::Str(pretty_time(meta, MetadataTimeField::Change)), // time of last status change, seconds since Epoch - 'Z' => OutputType::Integer(meta.ctime()), + 'Z' => { + let (sec, nsec) = metadata_get_time(meta, MetadataTimeField::Change) + .map_or((0, 0), system_time_to_sec); + OutputType::Float(sec as f64 + nsec as f64 / 1_000_000_000.0) + } 'R' => { let major = meta.rdev() >> 8; let minor = meta.rdev() & 0xff; diff --git a/tests/by-util/test_stat.rs b/tests/by-util/test_stat.rs index 318735476..0aad7361b 100644 --- a/tests/by-util/test_stat.rs +++ b/tests/by-util/test_stat.rs @@ -194,14 +194,14 @@ fn test_char() { #[cfg(target_os = "linux")] #[test] -fn test_printf_mtime_precision() { +fn test_printf_atime_ctime_mtime_precision() { // TODO Higher precision numbers (`%.3Y`, `%.4Y`, etc.) are // formatted correctly, but we are not precise enough when we do // some `mtime` computations, so we get `.7640` instead of // `.7639`. This can be fixed by being more careful when // transforming the number from `Metadata::mtime_nsec()` to the form // used in rendering. - let args = ["-c", "%.0Y %.1Y %.2Y", "/dev/pts/ptmx"]; + let args = ["-c", "%.0Y %.1Y %.2X %.2Y %.2Z", "/dev/pts/ptmx"]; let ts = TestScenario::new(util_name!()); let expected_stdout = unwrap_or_return!(expected_result(&ts, &args)).stdout_move_str(); eprintln!("{expected_stdout}");