From aaea758b6a7865ee786ac743a1828d08ae3e370e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 22 Apr 2023 08:56:01 +0200 Subject: [PATCH] touch: -h should not fail when running on broken symlink Fixes more of tests/touch/no-dereference.sh --- src/uu/touch/src/touch.rs | 13 ++++++++++++- tests/by-util/test_touch.rs | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 8d96b1b16..de1924134 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -139,15 +139,25 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let path = pathbuf.as_path(); - if let Err(e) = path.metadata() { + // Check the metadata of the path + let metadata_result = if matches.get_flag(options::NO_DEREF) { + path.symlink_metadata() + } else { + path.metadata() + }; + + if let Err(e) = metadata_result { + // If the error is not a NotFound error, return the error with context if e.kind() != std::io::ErrorKind::NotFound { return Err(e.map_err_context(|| format!("setting times of {}", filename.quote()))); } + // If the NO_CREATE flag is set, skip this iteration if matches.get_flag(options::NO_CREATE) { continue; } + // If the NO_DEREF flag is set, show an error and skip this iteration if matches.get_flag(options::NO_DEREF) { show!(USimpleError::new( 1, @@ -159,6 +169,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { continue; } + // Create the file, and handle errors by showing the error and skipping this iteration if let Err(e) = File::create(path) { show!(e.map_err_context(|| format!("cannot touch {}", path.quote()))); continue; diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index 89a7cacaf..a2e378777 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -825,3 +825,11 @@ fn test_touch_no_dereference_ref_dangling() { ucmd.args(&["-h", "-r", "dangling", "file"]).succeeds(); } + +#[test] +fn test_touch_no_dereference_dangling() { + let (at, mut ucmd) = at_and_ucmd!(); + at.relative_symlink_file("nowhere", "dangling"); + + ucmd.args(&["-h", "dangling"]).succeeds(); +}