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)); +}