diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 07635881a..e01af5195 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -15,7 +15,7 @@ use chrono::Local; use std::collections::HashSet; use std::env; use std::fs; -use std::io::{stderr, Result, Write}; +use std::io::{stderr, ErrorKind, Result, Write}; use std::iter; #[cfg(not(windows))] use std::os::unix::fs::MetadataExt; @@ -296,7 +296,21 @@ fn du( } } } - Err(error) => show_error!("{}", error), + Err(error) => match error.kind() { + ErrorKind::PermissionDenied => { + let description = format!( + "cannot access '{}'", + entry + .path() + .as_os_str() + .to_str() + .unwrap_or("") + ); + let error_message = "Permission denied"; + show_error_custom_description!(description, "{}", error_message) + } + _ => show_error!("{}", error), + }, }, Err(error) => show_error!("{}", error), } diff --git a/src/uucore/src/lib/macros.rs b/src/uucore/src/lib/macros.rs index 24b392ebd..637e91f8f 100644 --- a/src/uucore/src/lib/macros.rs +++ b/src/uucore/src/lib/macros.rs @@ -31,6 +31,14 @@ macro_rules! show_error( ); /// Show a warning to stderr in a silimar style to GNU coreutils. +#[macro_export] +macro_rules! show_error_custom_description ( + ($err:expr,$($args:tt)+) => ({ + eprint!("{}: {}: ", executable!(), $err); + eprintln!($($args)+); + }) +); + #[macro_export] macro_rules! show_warning( ($($args:tt)+) => ({ diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index 8f2cff65d..f668edeef 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -190,3 +190,33 @@ fn test_du_time() { assert_eq!(result.stderr, ""); assert_eq!(result.stdout, "0\t2015-05-15 00:00\tdate_test\n"); } + +#[cfg(not(target_os = "windows"))] +#[cfg(feature = "chmod")] +#[test] +fn test_du_no_permission() { + let ts = TestScenario::new("du"); + + let chmod = ts.ccmd("chmod").arg("-r").arg(SUB_DIR_LINKS).run(); + println!("chmod output: {:?}", chmod); + assert!(chmod.success); + let result = ts.ucmd().arg(SUB_DIR_LINKS).run(); + + ts.ccmd("chmod").arg("+r").arg(SUB_DIR_LINKS).run(); + + assert!(result.success); + assert_eq!( + result.stderr, + "du: cannot read directory ‘subdir/links‘: Permission denied (os error 13)\n" + ); + _du_no_permission(result.stdout); +} + +#[cfg(target_vendor = "apple")] +fn _du_no_permission(s: String) { + assert_eq!(s, "0\tsubdir/links\n"); +} +#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))] +fn _du_no_permission(s: String) { + assert_eq!(s, "4\tsubdir/links\n"); +}