1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-01 13:37:48 +00:00

touch: -h -r should not fail when running on broken symlink

Fixes the beginning of:
tests/touch/no-dereference.sh
This commit is contained in:
Sylvestre Ledru 2023-04-21 23:54:08 +02:00
parent afa5c15581
commit c3656e561c
2 changed files with 23 additions and 6 deletions

View file

@ -305,13 +305,21 @@ pub fn uu_app() -> Command {
) )
} }
// Function to get metadata of the provided path
// If `follow` is true, the function will try to follow symlinks
// If `follow` is false or the symlink is broken, the function will return metadata of the symlink itself
fn stat(path: &Path, follow: bool) -> UResult<(FileTime, FileTime)> { fn stat(path: &Path, follow: bool) -> UResult<(FileTime, FileTime)> {
let metadata = if follow { // Try to get metadata using fs::metadata
fs::symlink_metadata(path) // If the path is a symlink and `follow` is true, fs::metadata will follow the symlink
} else { let metadata = match fs::metadata(path) {
fs::metadata(path) // If successful, use the metadata
} Ok(metadata) => metadata,
.map_err_context(|| format!("failed to get attributes of {}", path.quote()))?; // If there's a NotFound error and `follow` is false, try to get metadata of the symlink itself
Err(e) if e.kind() == std::io::ErrorKind::NotFound && !follow => fs::symlink_metadata(path)
.map_err_context(|| format!("failed to get attributes of {}", path.quote()))?,
// If it's any other error, return the error
Err(e) => return Err(e.into()),
};
Ok(( Ok((
FileTime::from_last_access_time(&metadata), FileTime::from_last_access_time(&metadata),

View file

@ -816,3 +816,12 @@ fn test_touch_trailing_slash_no_create() {
at.relative_symlink_dir("dir2", "link2"); at.relative_symlink_dir("dir2", "link2");
ucmd.args(&["-c", "link2/"]).succeeds(); ucmd.args(&["-c", "link2/"]).succeeds();
} }
#[test]
fn test_touch_no_dereference_ref_dangling() {
let (at, mut ucmd) = at_and_ucmd!();
at.touch("file");
at.relative_symlink_file("nowhere", "dangling");
ucmd.args(&["-h", "-r", "dangling", "file"]).succeeds();
}