mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
uucore::fs add an hardlink detection
This commit is contained in:
parent
93f28dacc0
commit
b7cf825887
1 changed files with 74 additions and 1 deletions
|
@ -617,14 +617,47 @@ pub fn is_symlink_loop(path: &Path) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
// Hard link comparison is not supported on non-Unix platforms
|
||||||
|
pub fn are_hardlinks_to_same_file(_source: &Path, _target: &Path) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if two paths are hard links to the same file.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `source` - A reference to a `Path` representing the source path.
|
||||||
|
/// * `target` - A reference to a `Path` representing the target path.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// * `bool` - Returns `true` if the paths are hard links to the same file, and `false` otherwise.
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub fn are_hardlinks_to_same_file(source: &Path, target: &Path) -> bool {
|
||||||
|
let source_metadata = match fs::metadata(source) {
|
||||||
|
Ok(metadata) => metadata,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_metadata = match fs::metadata(target) {
|
||||||
|
Ok(metadata) => metadata,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
source_metadata.ino() == target_metadata.ino() && source_metadata.dev() == target_metadata.dev()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
||||||
use super::*;
|
use super::*;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
use std::io::Write;
|
||||||
|
#[cfg(unix)]
|
||||||
use std::os::unix;
|
use std::os::unix;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use tempfile::tempdir;
|
use tempfile::{tempdir, NamedTempFile};
|
||||||
|
|
||||||
struct NormalizePathTestCase<'a> {
|
struct NormalizePathTestCase<'a> {
|
||||||
path: &'a str,
|
path: &'a str,
|
||||||
|
@ -769,4 +802,44 @@ mod tests {
|
||||||
|
|
||||||
assert!(is_symlink_loop(&symlink1_path));
|
assert!(is_symlink_loop(&symlink1_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[test]
|
||||||
|
fn test_are_hardlinks_to_same_file_same_file() {
|
||||||
|
let mut temp_file = NamedTempFile::new().unwrap();
|
||||||
|
writeln!(temp_file, "Test content").unwrap();
|
||||||
|
|
||||||
|
let path1 = temp_file.path();
|
||||||
|
let path2 = temp_file.path();
|
||||||
|
|
||||||
|
assert_eq!(are_hardlinks_to_same_file(&path1, &path2), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[test]
|
||||||
|
fn test_are_hardlinks_to_same_file_different_files() {
|
||||||
|
let mut temp_file1 = NamedTempFile::new().unwrap();
|
||||||
|
writeln!(temp_file1, "Test content 1").unwrap();
|
||||||
|
|
||||||
|
let mut temp_file2 = NamedTempFile::new().unwrap();
|
||||||
|
writeln!(temp_file2, "Test content 2").unwrap();
|
||||||
|
|
||||||
|
let path1 = temp_file1.path();
|
||||||
|
let path2 = temp_file2.path();
|
||||||
|
|
||||||
|
assert_eq!(are_hardlinks_to_same_file(&path1, &path2), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[test]
|
||||||
|
fn test_are_hardlinks_to_same_file_hard_link() {
|
||||||
|
let mut temp_file = NamedTempFile::new().unwrap();
|
||||||
|
writeln!(temp_file, "Test content").unwrap();
|
||||||
|
let path1 = temp_file.path();
|
||||||
|
|
||||||
|
let path2 = temp_file.path().with_extension("hardlink");
|
||||||
|
fs::hard_link(&path1, &path2).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(are_hardlinks_to_same_file(&path1, &path2), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue