@@ -19,8 +19,9 @@ use term_grid::SPACES_IN_TAB;
1919
2020use uucore:: {
2121 display:: Quotable , error:: UResult , format:: human:: SizeFormat , fsext:: MetadataTimeField ,
22- line_ending:: LineEnding , parser:: parse_glob, parser:: parse_size:: parse_size_non_zero_u64,
23- quoting_style:: QuotingStyle , show_error, show_warning, time:: format, translate,
22+ line_ending:: LineEnding , parser:: parse_block_size, parser:: parse_glob,
23+ parser:: parse_size:: parse_size_non_zero_u64, quoting_style:: QuotingStyle , show_error,
24+ show_warning, time:: format, translate,
2425} ;
2526
2627use crate :: {
@@ -123,6 +124,49 @@ const POSIXLY_CORRECT_BLOCK_SIZE: u64 = 512;
123124const DEFAULT_BLOCK_SIZE : u64 = 1024 ;
124125const DEFAULT_FILE_SIZE_BLOCK_SIZE : u64 = 1 ;
125126
127+ /// Resolve `(file_size_block_size, block_size)` from environment variables.
128+ ///
129+ /// `LS_BLOCK_SIZE` and `BLOCK_SIZE` affect both values.
130+ /// `BLOCKSIZE` only affects `block_size` (allocation display with `-s`).
131+ /// `POSIXLY_CORRECT` sets `block_size` to 512 as a last resort.
132+ /// `-k` (`opt_kb`) forces `block_size` to `DEFAULT_BLOCK_SIZE`.
133+ fn resolve_block_sizes_from_env ( opt_kb : bool ) -> ( u64 , u64 ) {
134+ match parse_block_size:: block_size_from_env ( & [ "LS_BLOCK_SIZE" , "BLOCK_SIZE" ] ) {
135+ parse_block_size:: BlockSizeEnv :: Found ( size) => {
136+ if opt_kb {
137+ ( size, DEFAULT_BLOCK_SIZE )
138+ } else {
139+ ( size, size)
140+ }
141+ }
142+ parse_block_size:: BlockSizeEnv :: SetButInvalid => ( DEFAULT_BLOCK_SIZE , DEFAULT_BLOCK_SIZE ) ,
143+ parse_block_size:: BlockSizeEnv :: NotSet => {
144+ // Neither LS_BLOCK_SIZE nor BLOCK_SIZE was set; check BLOCKSIZE
145+ // which only affects allocation display, not file size.
146+ match parse_block_size:: block_size_from_env ( & [ "BLOCKSIZE" ] ) {
147+ parse_block_size:: BlockSizeEnv :: Found ( size) => {
148+ if opt_kb {
149+ ( DEFAULT_FILE_SIZE_BLOCK_SIZE , DEFAULT_BLOCK_SIZE )
150+ } else {
151+ ( DEFAULT_FILE_SIZE_BLOCK_SIZE , size)
152+ }
153+ }
154+ parse_block_size:: BlockSizeEnv :: SetButInvalid => {
155+ // BLOCKSIZE was set but invalid: stop lookup, use defaults.
156+ ( DEFAULT_FILE_SIZE_BLOCK_SIZE , DEFAULT_BLOCK_SIZE )
157+ }
158+ parse_block_size:: BlockSizeEnv :: NotSet => {
159+ if std:: env:: var_os ( "POSIXLY_CORRECT" ) . is_some ( ) && !opt_kb {
160+ ( DEFAULT_FILE_SIZE_BLOCK_SIZE , POSIXLY_CORRECT_BLOCK_SIZE )
161+ } else {
162+ ( DEFAULT_FILE_SIZE_BLOCK_SIZE , DEFAULT_BLOCK_SIZE )
163+ }
164+ }
165+ }
166+ }
167+ }
168+ }
169+
126170pub ( crate ) enum Dereference {
127171 None ,
128172 DirArgs ,
@@ -704,61 +748,23 @@ impl Config {
704748 SizeFormat :: Bytes
705749 } ;
706750
707- let env_var_blocksize = std:: env:: var_os ( "BLOCKSIZE" ) ;
708- let env_var_block_size = std:: env:: var_os ( "BLOCK_SIZE" ) ;
709- let env_var_ls_block_size = std:: env:: var_os ( "LS_BLOCK_SIZE" ) ;
710- let env_var_posixly_correct = std:: env:: var_os ( "POSIXLY_CORRECT" ) ;
711- let mut is_env_var_blocksize = false ;
712-
713- let raw_block_size = if let Some ( opt_block_size) = opt_block_size {
714- OsString :: from ( opt_block_size)
715- } else if let Some ( env_var_ls_block_size) = env_var_ls_block_size {
716- env_var_ls_block_size
717- } else if let Some ( env_var_block_size) = env_var_block_size {
718- env_var_block_size
719- } else if let Some ( env_var_blocksize) = env_var_blocksize {
720- is_env_var_blocksize = true ;
721- env_var_blocksize
722- } else {
723- OsString :: from ( "" )
724- } ;
725-
726- let ( file_size_block_size, block_size) = if !opt_si && !opt_hr && !raw_block_size. is_empty ( )
727- {
728- if let Ok ( size) = parse_size_non_zero_u64 ( & raw_block_size. to_string_lossy ( ) ) {
729- match ( is_env_var_blocksize, opt_kb) {
730- ( true , true ) => ( DEFAULT_FILE_SIZE_BLOCK_SIZE , DEFAULT_BLOCK_SIZE ) ,
731- ( true , false ) => ( DEFAULT_FILE_SIZE_BLOCK_SIZE , size) ,
732- ( false , true ) => {
733- // --block-size overrides -k
734- if opt_block_size. is_some ( ) {
735- ( size, size)
736- } else {
737- ( size, DEFAULT_BLOCK_SIZE )
738- }
739- }
740- ( false , false ) => ( size, size) ,
741- }
742- } else {
743- // only fail if invalid block size was specified with --block-size,
744- // ignore invalid block size from env vars
745- if let Some ( invalid_block_size) = opt_block_size {
746- return Err ( Box :: new ( LsError :: BlockSizeParseError (
747- invalid_block_size. clone ( ) ,
748- ) ) ) ;
749- }
750- if is_env_var_blocksize {
751- ( DEFAULT_FILE_SIZE_BLOCK_SIZE , DEFAULT_BLOCK_SIZE )
752- } else {
753- ( DEFAULT_BLOCK_SIZE , DEFAULT_BLOCK_SIZE )
754- }
755- }
756- } else if env_var_posixly_correct. is_some ( ) {
757- if opt_kb {
751+ let ( file_size_block_size, block_size) = if let Some ( opt_block_size) = opt_block_size {
752+ // --block-size command-line argument: parse it, error on invalid
753+ // If --block-size=si or --block-size=human-readable, skip numeric parsing
754+ if opt_si {
755+ ( DEFAULT_FILE_SIZE_BLOCK_SIZE , 1000 )
756+ } else if opt_hr {
758757 ( DEFAULT_FILE_SIZE_BLOCK_SIZE , DEFAULT_BLOCK_SIZE )
758+ } else if let Ok ( size) = parse_size_non_zero_u64 ( opt_block_size) {
759+ // --block-size overrides -k
760+ ( size, size)
759761 } else {
760- ( DEFAULT_FILE_SIZE_BLOCK_SIZE , POSIXLY_CORRECT_BLOCK_SIZE )
762+ return Err ( Box :: new ( LsError :: BlockSizeParseError (
763+ opt_block_size. clone ( ) ,
764+ ) ) ) ;
761765 }
766+ } else if !opt_si && !opt_hr {
767+ resolve_block_sizes_from_env ( opt_kb)
762768 } else if opt_si {
763769 ( DEFAULT_FILE_SIZE_BLOCK_SIZE , 1000 )
764770 } else {
0 commit comments