summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/uu/ls/src/ls.rs70
-rw-r--r--tests/by-util/test_ls.rs47
2 files changed, 74 insertions, 43 deletions
diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs
index f45f46b13..7ad1704fc 100644
--- a/src/uu/ls/src/ls.rs
+++ b/src/uu/ls/src/ls.rs
@@ -161,8 +161,8 @@ pub mod options {
const DEFAULT_TERM_WIDTH: u16 = 80;
const POSIXLY_CORRECT_BLOCK_SIZE: u64 = 512;
-#[cfg(unix)]
const DEFAULT_BLOCK_SIZE: u64 = 1024;
+const DEFAULT_FILE_SIZE_BLOCK_SIZE: u64 = 1;
#[derive(Debug)]
enum LsError {
@@ -409,7 +409,9 @@ pub struct Config {
color: Option<LsColors>,
long: LongFormat,
alloc_size: bool,
- block_size: Option<u64>,
+ file_size_block_size: u64,
+ #[allow(dead_code)]
+ block_size: u64, // is never read on Windows
width: u16,
// Dir and vdir needs access to this field
pub quoting_style: QuotingStyle,
@@ -822,6 +824,7 @@ impl Config {
let env_var_block_size = std::env::var_os("BLOCK_SIZE");
let env_var_ls_block_size = std::env::var_os("LS_BLOCK_SIZE");
let env_var_posixly_correct = std::env::var_os("POSIXLY_CORRECT");
+ let mut is_env_var_blocksize = false;
let raw_block_size = if let Some(opt_block_size) = opt_block_size {
OsString::from(opt_block_size)
@@ -831,6 +834,7 @@ impl Config {
} else if let Some(env_var_block_size) = env_var_block_size {
env_var_block_size
} else if let Some(env_var_blocksize) = env_var_blocksize {
+ is_env_var_blocksize = true;
env_var_blocksize
} else {
OsString::from("")
@@ -839,9 +843,16 @@ impl Config {
OsString::from("")
};
- let block_size: Option<u64> = if !opt_si && !opt_hr && !raw_block_size.is_empty() {
+ let (file_size_block_size, block_size) = if !opt_si && !opt_hr && !raw_block_size.is_empty()
+ {
match parse_size_u64(&raw_block_size.to_string_lossy()) {
- Ok(size) => Some(size),
+ Ok(size) => {
+ if is_env_var_blocksize {
+ (DEFAULT_FILE_SIZE_BLOCK_SIZE, size)
+ } else {
+ (size, size)
+ }
+ }
Err(_) => {
// only fail if invalid block size was specified with --block-size,
// ignore invalid block size from env vars
@@ -850,13 +861,19 @@ impl Config {
invalid_block_size.clone(),
)));
}
- None
+ if is_env_var_blocksize {
+ (DEFAULT_FILE_SIZE_BLOCK_SIZE, DEFAULT_BLOCK_SIZE)
+ } else {
+ (DEFAULT_BLOCK_SIZE, DEFAULT_BLOCK_SIZE)
+ }
}
}
} else if env_var_posixly_correct.is_some() {
- Some(POSIXLY_CORRECT_BLOCK_SIZE)
+ (DEFAULT_FILE_SIZE_BLOCK_SIZE, POSIXLY_CORRECT_BLOCK_SIZE)
+ } else if opt_si {
+ (DEFAULT_FILE_SIZE_BLOCK_SIZE, 1000)
} else {
- None
+ (DEFAULT_FILE_SIZE_BLOCK_SIZE, DEFAULT_BLOCK_SIZE)
};
let long = {
@@ -1062,6 +1079,7 @@ impl Config {
inode: options.get_flag(options::INODE),
long,
alloc_size: options.get_flag(options::size::ALLOCATION_SIZE),
+ file_size_block_size,
block_size,
width,
quoting_style,
@@ -2479,13 +2497,7 @@ fn get_block_size(md: &Metadata, config: &Config) -> u64 {
};
match config.size_format {
SizeFormat::Binary | SizeFormat::Decimal => raw_blocks,
- SizeFormat::Bytes => {
- if let Some(user_block_size) = config.block_size {
- raw_blocks / user_block_size
- } else {
- raw_blocks / DEFAULT_BLOCK_SIZE
- }
- }
+ SizeFormat::Bytes => raw_blocks / config.block_size,
}
}
#[cfg(not(unix))]
@@ -2955,26 +2967,16 @@ fn display_len_or_rdev(metadata: &Metadata, config: &Config) -> SizeOrDeviceId {
return SizeOrDeviceId::Device(major.to_string(), minor.to_string());
}
}
- // Reported file len only adjusted for block_size when block_size is set
- if let Some(user_block_size) = config.block_size {
- // ordinary division of unsigned integers rounds down,
- // this is similar to the Rust API for division that rounds up,
- // currently in nightly only, however once
- // https://github.com/rust-lang/rust/pull/88582 : "div_ceil"
- // is stable we should use that instead
- let len_adjusted = {
- let d = metadata.len() / user_block_size;
- let r = metadata.len() % user_block_size;
- if r == 0 {
- d
- } else {
- d + 1
- }
- };
- SizeOrDeviceId::Size(display_size(len_adjusted, config))
- } else {
- SizeOrDeviceId::Size(display_size(metadata.len(), config))
- }
+ let len_adjusted = {
+ let d = metadata.len() / config.file_size_block_size;
+ let r = metadata.len() % config.file_size_block_size;
+ if r == 0 {
+ d
+ } else {
+ d + 1
+ }
+ };
+ SizeOrDeviceId::Size(display_size(len_adjusted, config))
}
fn display_size(size: u64, config: &Config) -> String {
diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs
index 8aeb762c7..a7744063f 100644
--- a/tests/by-util/test_ls.rs
+++ b/tests/by-util/test_ls.rs
@@ -3862,8 +3862,8 @@ fn test_posixly_correct_and_block_size_env_vars() {
.arg("-l")
.env("POSIXLY_CORRECT", "some_value")
.succeeds()
- .stdout_contains_line("total 8");
- //.stdout_contains(" 1024 "); // TODO needs second internal blocksize
+ .stdout_contains_line("total 8")
+ .stdout_contains(" 1024 ");
scene
.ucmd()
@@ -3886,8 +3886,8 @@ fn test_posixly_correct_and_block_size_env_vars() {
.arg("-l")
.env("BLOCKSIZE", "512")
.succeeds()
- .stdout_contains_line("total 8");
- //.stdout_contains(" 1024 "); // TODO needs second internal blocksize
+ .stdout_contains_line("total 8")
+ .stdout_contains(" 1024 ");
}
#[test]
@@ -3900,13 +3900,42 @@ fn test_ls_invalid_block_size() {
.stderr_is("ls: invalid --block-size argument 'invalid'\n");
}
-// TODO ensure the correct block size is used when using -l because
-// the output of "ls -l" and "BLOCK_SIZE=invalid ls -l" is different
+#[cfg(all(unix, feature = "dd"))]
#[test]
fn test_ls_invalid_block_size_in_env_var() {
- new_ucmd!().env("LS_BLOCK_SIZE", "invalid").succeeds();
- new_ucmd!().env("BLOCK_SIZE", "invalid").succeeds();
- new_ucmd!().env("BLOCKSIZE", "invalid").succeeds();
+ let scene = TestScenario::new(util_name!());
+
+ scene
+ .ccmd("dd")
+ .arg("if=/dev/zero")
+ .arg("of=file")
+ .arg("bs=1024")
+ .arg("count=1")
+ .succeeds();
+
+ scene
+ .ucmd()
+ .arg("-og")
+ .env("LS_BLOCK_SIZE", "invalid")
+ .succeeds()
+ .stdout_contains_line("total 4")
+ .stdout_contains(" 1 1 "); // hardlink count + file size
+
+ scene
+ .ucmd()
+ .arg("-og")
+ .env("BLOCK_SIZE", "invalid")
+ .succeeds()
+ .stdout_contains_line("total 4")
+ .stdout_contains(" 1 1 "); // hardlink count + file size
+
+ scene
+ .ucmd()
+ .arg("-og")
+ .env("BLOCKSIZE", "invalid")
+ .succeeds()
+ .stdout_contains_line("total 4")
+ .stdout_contains(" 1024 ");
}
#[cfg(all(unix, feature = "dd"))]