From 8b126868884d29b66beff21bbfb066cc4125fd63 Mon Sep 17 00:00:00 2001 From: Diego Magdaleno <38844659+DiegoMagdaleno@users.noreply.github.com> Date: Sat, 19 Dec 2020 10:54:28 -0600 Subject: [PATCH] ls: On Windows don't display files hidden by NTFS (#1662) This little check, allows us to hide the files that shouldn't be shown on the listing on Windows operating systems. Just like the "dot" in UNIX based operating systems Windows uses its own file attributes to determine if a file is hidden or not. The lack of support for this option is normally an annoyance for many users, this commit adds full support for this feature --- src/uu/ls/src/ls.rs | 14 +++++++++++++- tests/by-util/test_ls.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 20100568a..a2f8cab95 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -255,6 +255,18 @@ fn sort_entries(entries: &mut Vec, options: &getopts::Matches) { } } +#[cfg(windows)] +fn is_hidden(file_path: &DirEntry) -> std::io::Result { + let metadata = fs::metadata(file_path.path())?; + let attr = metadata.file_attributes(); + Ok(((attr & 0x2) > 0) || file_path.file_name().to_string_lossy().starts_with('.')) +} + +#[cfg(unix)] +fn is_hidden(file_path: &DirEntry) -> std::io::Result { + Ok(file_path.file_name().to_string_lossy().starts_with('.')) +} + #[cfg(windows)] fn sort_entries(entries: &mut Vec, options: &getopts::Matches) { let mut reverse = options.opt_present("r"); @@ -286,7 +298,7 @@ fn sort_entries(entries: &mut Vec, options: &getopts::Matches) { fn should_display(entry: &DirEntry, options: &getopts::Matches) -> bool { let ffi_name = entry.file_name(); let name = ffi_name.to_string_lossy(); - if !options.opt_present("a") && !options.opt_present("A") && name.starts_with('.') { + if !options.opt_present("a") && !options.opt_present("A") && is_hidden(entry).unwrap() { return false; } if options.opt_present("B") && name.ends_with('~') { diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 270849d95..4dc4168de 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -310,3 +310,29 @@ fn test_ls_human() { assert!(result.success); assert!(result.stdout.contains("1.02M")); } + +#[cfg(windows)] +#[test] +fn test_ls_hidden_windows() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + let file = "hiddenWindowsFileNoDot"; + at.touch(file); + // hide the file + scene + .cmd("attrib") + .arg("+h") + .arg("+S") + .arg("+r") + .arg(file) + .run(); + let result = scene.ucmd().run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(result.success); + let result = scene.ucmd().arg("-a").run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(result.success); + assert!(result.stdout.contains(file)); +}