From afa5c15581fad94882f922f5db89f287c0a57489 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 21 Apr 2023 16:53:15 +0200 Subject: [PATCH 1/5] gnu test: don't sync the po files We aren't testing the locale yet. --- util/build-gnu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index 9035fa69b..486cf3227 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -67,7 +67,7 @@ if test -f gnu-built; then echo "'rm -f $(pwd)/gnu-built' to force the build" echo "Note: the customization of the tests will still happen" else - ./bootstrap + ./bootstrap --skip-po ./configure --quiet --disable-gcc-warnings #Add timeout to to protect against hangs sed -i 's|^"\$@|/usr/bin/timeout 600 "\$@|' build-aux/test-driver From c3656e561cde70c2a860d11a5747c24387105b20 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 21 Apr 2023 23:54:08 +0200 Subject: [PATCH 2/5] touch: -h -r should not fail when running on broken symlink Fixes the beginning of: tests/touch/no-dereference.sh --- src/uu/touch/src/touch.rs | 20 ++++++++++++++------ tests/by-util/test_touch.rs | 9 +++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index eeb1dd13a..8d96b1b16 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -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)> { - let metadata = if follow { - fs::symlink_metadata(path) - } else { - fs::metadata(path) - } - .map_err_context(|| format!("failed to get attributes of {}", path.quote()))?; + // Try to get metadata using fs::metadata + // If the path is a symlink and `follow` is true, fs::metadata will follow the symlink + let metadata = match fs::metadata(path) { + // If successful, use the metadata + Ok(metadata) => metadata, + // 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(( FileTime::from_last_access_time(&metadata), diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index ae3a28e49..89a7cacaf 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -816,3 +816,12 @@ fn test_touch_trailing_slash_no_create() { at.relative_symlink_dir("dir2", "link2"); 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(); +} From aaea758b6a7865ee786ac743a1828d08ae3e370e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 22 Apr 2023 08:56:01 +0200 Subject: [PATCH 3/5] 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(); +} From 84e061048753656b3f4eaf627e8d6efef1034190 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 22 Apr 2023 18:54:43 +0200 Subject: [PATCH 4/5] touch: don't generate an error on 'touch -h -' --- src/uu/touch/src/touch.rs | 18 ++++++++++++++---- tests/by-util/test_touch.rs | 7 +++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index de1924134..45a51f02d 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -209,14 +209,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } - if matches.get_flag(options::NO_DEREF) { - set_symlink_file_times(path, atime, mtime) - } else { + // sets the file access and modification times for a file or a symbolic link. + // The filename, access time (atime), and modification time (mtime) are provided as inputs. + + // If the filename is not "-", indicating a special case for touch -h -, + // the code checks if the NO_DEREF flag is set, which means the user wants to + // set the times for a symbolic link itself, rather than the file it points to. + if filename == "-" { filetime::set_file_times(path, atime, mtime) + } else { + let should_set_symlink_times = matches.get_flag(options::NO_DEREF); + if should_set_symlink_times { + set_symlink_file_times(path, atime, mtime) + } else { + filetime::set_file_times(path, atime, mtime) + } } .map_err_context(|| format!("setting times of {}", path.quote()))?; } - Ok(()) } diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index a2e378777..7d2b8ad3f 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -833,3 +833,10 @@ fn test_touch_no_dereference_dangling() { ucmd.args(&["-h", "dangling"]).succeeds(); } + +#[test] +fn test_touch_dash() { + let (_, mut ucmd) = at_and_ucmd!(); + + ucmd.args(&["-h", "-"]).succeeds().no_stderr().no_stdout(); +} From c262fa936c758fdf4db2d931ee6bbb6ca62147fd Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 24 Apr 2023 11:47:59 +0200 Subject: [PATCH 5/5] Improve the doc and simplify the code Co-authored-by: Daniel Hofstetter --- src/uu/touch/src/touch.rs | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 45a51f02d..818a8c9f6 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -139,7 +139,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let path = pathbuf.as_path(); - // Check the metadata of the path let metadata_result = if matches.get_flag(options::NO_DEREF) { path.symlink_metadata() } else { @@ -147,17 +146,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }; 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, @@ -169,7 +165,6 @@ 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; @@ -217,13 +212,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // set the times for a symbolic link itself, rather than the file it points to. if filename == "-" { filetime::set_file_times(path, atime, mtime) + } else if matches.get_flag(options::NO_DEREF) { + set_symlink_file_times(path, atime, mtime) } else { - let should_set_symlink_times = matches.get_flag(options::NO_DEREF); - if should_set_symlink_times { - set_symlink_file_times(path, atime, mtime) - } else { - filetime::set_file_times(path, atime, mtime) - } + filetime::set_file_times(path, atime, mtime) } .map_err_context(|| format!("setting times of {}", path.quote()))?; } @@ -326,19 +318,14 @@ 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 +// 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)> { - // Try to get metadata using fs::metadata - // If the path is a symlink and `follow` is true, fs::metadata will follow the symlink let metadata = match fs::metadata(path) { - // If successful, use the metadata Ok(metadata) => metadata, - // 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()), };