Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions src/uu/du/src/du.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,14 +346,21 @@ fn du(
}

if let Some(inode) = this_stat.inode {
if seen_inodes.contains(&inode) {
if options.count_links {
// Check if the inode has been seen before and if we should skip it
if seen_inodes.contains(&inode)
&& (!options.count_links || !options.all)
{
// If `count_links` is enabled and `all` is not, increment the inode count
if options.count_links && !options.all {
my_stat.inodes += 1;
}
// Skip further processing for this inode
continue;
}
// Mark this inode as seen
seen_inodes.insert(inode);
}

if this_stat.is_dir {
if options.one_file_system {
if let (Some(this_inode), Some(my_inode)) =
Expand Down Expand Up @@ -550,9 +557,6 @@ impl StatPrinter {
}

fn convert_size(&self, size: u64) -> String {
if self.inodes {
return size.to_string();
}
match self.size_format {
SizeFormat::HumanDecimal => uucore::format::human::human_readable(
size,
Expand All @@ -562,7 +566,14 @@ impl StatPrinter {
size,
uucore::format::human::SizeFormat::Binary,
),
SizeFormat::BlockSize(block_size) => size.div_ceil(block_size).to_string(),
SizeFormat::BlockSize(block_size) => {
if self.inodes {
// we ignore block size (-B) with --inodes
size.to_string()
} else {
size.div_ceil(block_size).to_string()
}
}
}
}

Expand Down
49 changes: 49 additions & 0 deletions tests/by-util/test_du.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,33 @@ fn test_du_inodes_with_count_links() {
}
}

#[cfg(not(target_os = "android"))]
#[test]
fn test_du_inodes_with_count_links_all() {
let ts = TestScenario::new(util_name!());
let at = &ts.fixtures;

at.mkdir("d");
at.mkdir("d/d");
at.touch("d/f");
at.hard_link("d/f", "d/h");

let result = ts.ucmd().arg("--inodes").arg("-al").arg("d").succeeds();
result.no_stderr();

let mut result_seq: Vec<String> = result
.stdout_str()
.split('\n')
.filter(|x| !x.is_empty())
.map(|x| x.parse().unwrap())
.collect();
result_seq.sort_unstable();
#[cfg(windows)]
assert_eq!(result_seq, ["1\td\\d", "1\td\\f", "1\td\\h", "4\td"]);
#[cfg(not(windows))]
assert_eq!(result_seq, ["1\td/d", "1\td/f", "1\td/h", "4\td"]);
}

#[test]
fn test_du_h_flag_empty_file() {
new_ucmd!()
Expand Down Expand Up @@ -1171,3 +1198,25 @@ fn test_invalid_time_style() {
.succeeds()
.stdout_does_not_contain("du: invalid argument 'banana' for 'time style'");
}

#[test]
fn test_human_size() {
use std::fs::File;

let ts = TestScenario::new(util_name!());
let at = &ts.fixtures;
let dir = at.plus_as_string("d");
at.mkdir(&dir);

for i in 1..=1023 {
let file_path = format!("{dir}/file{i}");
File::create(&file_path).expect("Failed to create file");
}

ts.ucmd()
.arg("--inodes")
.arg("-h")
.arg(&dir)
.succeeds()
.stdout_contains(format!("1.0K {dir}"));
}
Loading