From eb2c06c37e29ebdc97a58eeb4002bccae7a46709 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 2 Jun 2021 22:53:10 +0200 Subject: [PATCH] touch/gnu compat: when touch fails because of a permission error, change the error message + return 1 as error code when having this error --- src/uu/touch/src/touch.rs | 24 ++++++++++++++++++++---- tests/by-util/test_touch.rs | 10 ++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index b76e04b7a..ed65cb659 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -155,6 +155,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 { (now, now) }; + let mut error_code = 0; + for filename in &files { let path = &filename[..]; @@ -202,14 +204,28 @@ pub fn uumain(args: impl uucore::Args) -> i32 { if matches.is_present(options::NO_DEREF) { if let Err(e) = set_symlink_file_times(path, atime, mtime) { - show_warning!("cannot touch '{}': {}", path, e); + // we found an error, it should fail in any case + error_code = 1; + if e.kind() == std::io::ErrorKind::PermissionDenied { + // GNU compatibility (not-owner.sh) + show_error!("setting times of '{}': {}", path, "Permission denied"); + } else { + show_error!("setting times of '{}': {}", path, e); + } } } else if let Err(e) = filetime::set_file_times(path, atime, mtime) { - show_warning!("cannot touch '{}': {}", path, e); + // we found an error, it should fail in any case + error_code = 1; + + if e.kind() == std::io::ErrorKind::PermissionDenied { + // GNU compatibility (not-owner.sh) + show_error!("setting times of '{}': {}", path, "Permission denied"); + } else { + show_error!("setting times of '{}': {}", path, e); + } } } - - 0 + error_code } fn stat(path: &str, follow: bool) -> (FileTime, FileTime) { diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index 3c803e1c6..cd780f670 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -449,3 +449,13 @@ fn test_touch_mtime_dst_fails() { ucmd.args(&["-m", "-t", &s, file]).fails(); } } + +#[test] +#[cfg(unix)] +fn test_touch_system_fails() { + let (_at, mut ucmd) = at_and_ucmd!(); + let file = "/"; + ucmd.args(&[file]) + .fails() + .stderr_contains("setting times of '/'"); +}