mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
touch: Respect -h when getting metadata (#5951)
* Add tests that stat symlinks * Check follow first in stat * Don't run tests on FreeBSD It would be possible to get them to run on FreeBSD by avoiding get_symlink_times, but the behavior we're testing is not platform-specific, so it's fine to not test it on FreeBSD. --------- Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
This commit is contained in:
parent
8c7940260b
commit
d11d595fda
2 changed files with 44 additions and 7 deletions
|
@ -326,12 +326,12 @@ fn update_times(
|
||||||
// If `follow` is `true`, the function will try to follow symlinks
|
// 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
|
// 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 = match fs::metadata(path) {
|
let metadata = if follow {
|
||||||
Ok(metadata) => metadata,
|
fs::metadata(path).or_else(|_| fs::symlink_metadata(path))
|
||||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound && !follow => fs::symlink_metadata(path)
|
} else {
|
||||||
.map_err_context(|| format!("failed to get attributes of {}", path.quote()))?,
|
fs::symlink_metadata(path)
|
||||||
Err(e) => return Err(e.into()),
|
}
|
||||||
};
|
.map_err_context(|| format!("failed to get attributes of {}", path.quote()))?;
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
FileTime::from_last_access_time(&metadata),
|
FileTime::from_last_access_time(&metadata),
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// spell-checker:ignore (formats) cymdhm cymdhms mdhm mdhms ymdhm ymdhms datetime mktime
|
// spell-checker:ignore (formats) cymdhm cymdhms mdhm mdhms ymdhm ymdhms datetime mktime
|
||||||
|
|
||||||
use crate::common::util::{AtPath, TestScenario};
|
use crate::common::util::{AtPath, TestScenario};
|
||||||
use filetime::FileTime;
|
use filetime::{self, set_symlink_file_times, FileTime};
|
||||||
use std::fs::remove_file;
|
use std::fs::remove_file;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
@ -854,3 +854,40 @@ fn test_touch_invalid_date_format() {
|
||||||
.fails()
|
.fails()
|
||||||
.stderr_contains("touch: invalid date format '+1000000000000 years'");
|
.stderr_contains("touch: invalid date format '+1000000000000 years'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
|
fn test_touch_symlink_with_no_deref() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let target = "foo.txt";
|
||||||
|
let symlink = "bar.txt";
|
||||||
|
let time = FileTime::from_unix_time(123, 0);
|
||||||
|
|
||||||
|
at.touch(target);
|
||||||
|
at.relative_symlink_file(target, symlink);
|
||||||
|
set_symlink_file_times(at.plus(symlink), time, time).unwrap();
|
||||||
|
|
||||||
|
ucmd.args(&["-a", "--no-dereference", symlink]).succeeds();
|
||||||
|
// Modification time shouldn't be set to the destination's modification time
|
||||||
|
assert_eq!(time, get_symlink_times(&at, symlink).1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
|
fn test_touch_reference_symlink_with_no_deref() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let target = "foo.txt";
|
||||||
|
let symlink = "bar.txt";
|
||||||
|
let arg = "baz.txt";
|
||||||
|
let time = FileTime::from_unix_time(123, 0);
|
||||||
|
|
||||||
|
at.touch(target);
|
||||||
|
at.relative_symlink_file(target, symlink);
|
||||||
|
set_symlink_file_times(at.plus(symlink), time, time).unwrap();
|
||||||
|
at.touch(arg);
|
||||||
|
|
||||||
|
ucmd.args(&["--reference", symlink, "--no-dereference", arg])
|
||||||
|
.succeeds();
|
||||||
|
// Times should be taken from the symlink, not the destination
|
||||||
|
assert_eq!((time, time), get_symlink_times(&at, arg));
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue