From f28d5f4a73c19775c3892d09c808aa4a98f473c7 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Mon, 15 Mar 2021 12:07:10 +0100 Subject: [PATCH] ls: attempt to fix windows sorting issues --- src/uu/ls/src/ls.rs | 48 +++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 187b39006..90e4e2b22 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -27,6 +27,7 @@ use std::os::unix::fs::MetadataExt; #[cfg(windows)] use std::os::windows::fs::MetadataExt; use std::path::{Path, PathBuf}; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; use time::{strftime, Timespec}; @@ -532,8 +533,8 @@ fn sort_entries(entries: &mut Vec, config: &Config) { Reverse( get_metadata(k, config) .ok() - .and_then(|md| get_time(&md, config)) - .unwrap_or(0), + .and_then(|md| get_system_time(&md, config)) + .unwrap_or(UNIX_EPOCH), ) }), Sort::Size => entries @@ -756,34 +757,35 @@ fn display_group(_metadata: &Metadata, _config: &Config) -> String { // The implementations for get_time are separated because some options, such // as ctime will not be available #[cfg(unix)] -fn get_time(md: &Metadata, config: &Config) -> Option { - Some(match config.time { - Time::Change => md.ctime(), - Time::Modification => md.mtime(), - Time::Access => md.atime(), - }) +fn get_system_time(md: &Metadata, config: &Config) -> Option { + match config.time { + Time::Change => Some(UNIX_EPOCH + Duration::new(md.ctime() as u64, md.ctime_nsec() as u32)), + Time::Modification => md.modified().ok(), + Time::Access => md.accessed().ok(), + } } #[cfg(not(unix))] -fn get_time(md: &Metadata, config: &Config) -> Option { - let time = match config.time { - Time::Modification => md.modified().ok()?, - Time::Access => md.accessed().ok()?, - _ => return None, - }; - Some( - time.duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_secs() as i64, - ) +fn get_system_time(md: &Metadata, config: &Config) -> Option { + match config.time { + Time::Modification => md.modified().ok(), + Time::Access => md.accessed().ok(), + _ => None, + } +} + +fn get_time(md: &Metadata, config: &Config) -> Option { + let duration = get_system_time(md, config)? + .duration_since(UNIX_EPOCH) + .ok()?; + let secs = duration.as_secs() as i64; + let nsec = duration.subsec_nanos() as i32; + Some(time::at(Timespec::new(secs, nsec))) } fn display_date(metadata: &Metadata, config: &Config) -> String { match get_time(metadata, config) { - Some(secs) => { - let time = time::at(Timespec::new(secs, 0)); - strftime("%F %R", &time).unwrap() - } + Some(time) => strftime("%F %R", &time).unwrap(), None => "???".into(), } }