mirror of
https://github.com/uutils/coreutils
synced 2024-11-05 14:21:32 +00:00
Merge pull request #4769 from sylvestre/touch
touch: improve support for dangling link
This commit is contained in:
commit
6115af6386
3 changed files with 50 additions and 10 deletions
|
@ -139,7 +139,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
|
|
||||||
let path = pathbuf.as_path();
|
let path = pathbuf.as_path();
|
||||||
|
|
||||||
if let Err(e) = path.metadata() {
|
let metadata_result = if matches.get_flag(options::NO_DEREF) {
|
||||||
|
path.symlink_metadata()
|
||||||
|
} else {
|
||||||
|
path.metadata()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = metadata_result {
|
||||||
if e.kind() != std::io::ErrorKind::NotFound {
|
if e.kind() != std::io::ErrorKind::NotFound {
|
||||||
return Err(e.map_err_context(|| format!("setting times of {}", filename.quote())));
|
return Err(e.map_err_context(|| format!("setting times of {}", filename.quote())));
|
||||||
}
|
}
|
||||||
|
@ -198,14 +204,21 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches.get_flag(options::NO_DEREF) {
|
// 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 if matches.get_flag(options::NO_DEREF) {
|
||||||
set_symlink_file_times(path, atime, mtime)
|
set_symlink_file_times(path, atime, mtime)
|
||||||
} else {
|
} else {
|
||||||
filetime::set_file_times(path, atime, mtime)
|
filetime::set_file_times(path, atime, mtime)
|
||||||
}
|
}
|
||||||
.map_err_context(|| format!("setting times of {}", path.quote()))?;
|
.map_err_context(|| format!("setting times of {}", path.quote()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,13 +318,16 @@ pub fn uu_app() -> Command {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
let metadata = match fs::metadata(path) {
|
||||||
fs::symlink_metadata(path)
|
Ok(metadata) => metadata,
|
||||||
} else {
|
Err(e) if e.kind() == std::io::ErrorKind::NotFound && !follow => fs::symlink_metadata(path)
|
||||||
fs::metadata(path)
|
.map_err_context(|| format!("failed to get attributes of {}", path.quote()))?,
|
||||||
}
|
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),
|
||||||
|
|
|
@ -829,3 +829,27 @@ 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_touch_dash() {
|
||||||
|
let (_, mut ucmd) = at_and_ucmd!();
|
||||||
|
|
||||||
|
ucmd.args(&["-h", "-"]).succeeds().no_stderr().no_stdout();
|
||||||
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ if test -f gnu-built; then
|
||||||
echo "'rm -f $(pwd)/gnu-built' to force the build"
|
echo "'rm -f $(pwd)/gnu-built' to force the build"
|
||||||
echo "Note: the customization of the tests will still happen"
|
echo "Note: the customization of the tests will still happen"
|
||||||
else
|
else
|
||||||
./bootstrap
|
./bootstrap --skip-po
|
||||||
./configure --quiet --disable-gcc-warnings
|
./configure --quiet --disable-gcc-warnings
|
||||||
#Add timeout to to protect against hangs
|
#Add timeout to to protect against hangs
|
||||||
sed -i 's|^"\$@|/usr/bin/timeout 600 "\$@|' build-aux/test-driver
|
sed -i 's|^"\$@|/usr/bin/timeout 600 "\$@|' build-aux/test-driver
|
||||||
|
|
Loading…
Reference in a new issue