mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
Merge pull request #1998 from paulotten/issue1969
Consider device id when comparing files
This commit is contained in:
commit
3f3b12ebcc
1 changed files with 26 additions and 12 deletions
|
@ -32,7 +32,7 @@ use winapi::um::minwinbase::{FileIdInfo, FileStandardInfo};
|
|||
#[cfg(windows)]
|
||||
use winapi::um::winbase::GetFileInformationByHandleEx;
|
||||
#[cfg(windows)]
|
||||
use winapi::um::winnt::FILE_ID_128;
|
||||
use winapi::um::winnt::{FILE_ID_128, ULONGLONG};
|
||||
|
||||
const NAME: &str = "du";
|
||||
const SUMMARY: &str = "estimate file space usage";
|
||||
|
@ -58,12 +58,18 @@ struct Options {
|
|||
separate_dirs: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
||||
struct FileInfo {
|
||||
file_id: u128,
|
||||
dev_id: u64,
|
||||
}
|
||||
|
||||
struct Stat {
|
||||
path: PathBuf,
|
||||
is_dir: bool,
|
||||
size: u64,
|
||||
blocks: u64,
|
||||
inode: Option<u128>,
|
||||
inode: Option<FileInfo>,
|
||||
created: u64,
|
||||
accessed: u64,
|
||||
modified: u64,
|
||||
|
@ -73,13 +79,18 @@ impl Stat {
|
|||
fn new(path: PathBuf) -> Result<Stat> {
|
||||
let metadata = fs::symlink_metadata(&path)?;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
let file_info = FileInfo {
|
||||
file_id: metadata.ino() as u128,
|
||||
dev_id: metadata.dev(),
|
||||
};
|
||||
#[cfg(not(windows))]
|
||||
return Ok(Stat {
|
||||
path,
|
||||
is_dir: metadata.is_dir(),
|
||||
size: metadata.len(),
|
||||
blocks: metadata.blocks() as u64,
|
||||
inode: Some(metadata.ino() as u128),
|
||||
inode: Some(file_info),
|
||||
created: metadata.mtime() as u64,
|
||||
accessed: metadata.atime() as u64,
|
||||
modified: metadata.mtime() as u64,
|
||||
|
@ -88,14 +99,14 @@ impl Stat {
|
|||
#[cfg(windows)]
|
||||
let size_on_disk = get_size_on_disk(&path);
|
||||
#[cfg(windows)]
|
||||
let inode = get_inode(&path);
|
||||
let file_info = get_file_info(&path);
|
||||
#[cfg(windows)]
|
||||
Ok(Stat {
|
||||
path,
|
||||
is_dir: metadata.is_dir(),
|
||||
size: metadata.len(),
|
||||
blocks: size_on_disk / 1024 * 2,
|
||||
inode: inode,
|
||||
inode: file_info,
|
||||
created: windows_time_to_unix_time(metadata.creation_time()),
|
||||
accessed: windows_time_to_unix_time(metadata.last_access_time()),
|
||||
modified: windows_time_to_unix_time(metadata.last_write_time()),
|
||||
|
@ -143,12 +154,12 @@ fn get_size_on_disk(path: &PathBuf) -> u64 {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_inode(path: &PathBuf) -> Option<u128> {
|
||||
let mut inode = None;
|
||||
fn get_file_info(path: &PathBuf) -> Option<FileInfo> {
|
||||
let mut result = None;
|
||||
|
||||
let file = match fs::File::open(path) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return inode,
|
||||
Err(_) => return result,
|
||||
};
|
||||
|
||||
let handle = file.as_raw_handle();
|
||||
|
@ -165,11 +176,14 @@ fn get_inode(path: &PathBuf) -> Option<u128> {
|
|||
);
|
||||
|
||||
if success != 0 {
|
||||
inode = Some(std::mem::transmute::<FILE_ID_128, u128>(file_info.FileId));
|
||||
result = Some(FileInfo {
|
||||
file_id: std::mem::transmute::<FILE_ID_128, u128>(file_info.FileId),
|
||||
dev_id: std::mem::transmute::<ULONGLONG, u64>(file_info.VolumeSerialNumber),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
inode
|
||||
result
|
||||
}
|
||||
|
||||
fn unit_string_to_number(s: &str) -> Option<u64> {
|
||||
|
@ -239,7 +253,7 @@ fn du(
|
|||
mut my_stat: Stat,
|
||||
options: &Options,
|
||||
depth: usize,
|
||||
inodes: &mut HashSet<u128>,
|
||||
inodes: &mut HashSet<FileInfo>,
|
||||
) -> Box<dyn DoubleEndedIterator<Item = Stat>> {
|
||||
let mut stats = vec![];
|
||||
let mut futures = vec![];
|
||||
|
@ -526,7 +540,7 @@ Try '{} --help' for more information.",
|
|||
let path = PathBuf::from(&path_str);
|
||||
match Stat::new(path) {
|
||||
Ok(stat) => {
|
||||
let mut inodes: HashSet<u128> = HashSet::new();
|
||||
let mut inodes: HashSet<FileInfo> = HashSet::new();
|
||||
|
||||
let iter = du(stat, &options, 0, &mut inodes);
|
||||
let (_, len) = iter.size_hint();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue