diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index be4e51041..efa436c81 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -166,7 +166,15 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } if let Err(e) = File::create(path) { - show_warning!("cannot touch '{}': {}", path, e); + match e.kind() { + std::io::ErrorKind::NotFound => { + show_error!("cannot touch '{}': {}", path, "No such file or directory") + } + std::io::ErrorKind::PermissionDenied => { + show_error!("cannot touch '{}': {}", path, "Permission denied") + } + _ => show_error!("cannot touch '{}': {}", path, e), + } error_code = 1; continue; }; diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index c861a50dd..5e8114092 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -6,6 +6,7 @@ use self::touch::filetime::{self, FileTime}; extern crate time; use crate::common::util::*; +use std::path::PathBuf; fn get_file_times(at: &AtPath, path: &str) -> (FileTime, FileTime) { let m = at.metadata(path); @@ -466,3 +467,37 @@ fn test_touch_trailing_slash() { let file = "no-file/"; ucmd.args(&[file]).fails(); } + +#[test] +fn test_touch_no_such_file_error_msg() { + let dirname = "nonexistent"; + let filename = "file"; + let path = PathBuf::from(dirname).join(filename); + let path_str = path.to_str().unwrap(); + + new_ucmd!().arg(&path).fails().stderr_only(format!( + "touch: cannot touch '{}': No such file or directory", + path_str + )); +} + +#[test] +#[cfg(unix)] +fn test_touch_permission_denied_error_msg() { + let (at, mut ucmd) = at_and_ucmd!(); + + let dirname = "dir_with_read_only_access"; + let filename = "file"; + let path = PathBuf::from(dirname).join(filename); + let path_str = path.to_str().unwrap(); + + // create dest without write permissions + at.mkdir(dirname); + at.set_readonly(dirname); + + let full_path = at.plus_as_string(path_str); + ucmd.arg(&full_path).fails().stderr_only(format!( + "touch: cannot touch '{}': Permission denied", + &full_path + )); +}