@@ -14,7 +14,7 @@ use uucore::format_usage;
1414use uucore:: parser:: shortcut_value_parser:: ShortcutValueParser ;
1515use uucore:: translate;
1616
17- // spell-checker:ignore nopipe
17+ // spell-checker:ignore espidf nopipe
1818
1919#[ cfg( target_os = "linux" ) ]
2020use uucore:: signals:: ensure_stdout_not_broken;
@@ -209,18 +209,33 @@ fn copy(mut input: impl Read, mut output: impl Write) -> Result<usize> {
209209 // the standard library:
210210 // https://github.com/rust-lang/rust/blob/2feb91181882e525e698c4543063f4d0296fcf91/library/std/src/io/copy.rs#L271-L297
211211
212- // Use buffer size from std implementation:
212+ // Use small buffer size from std implementation for small input
213213 // https://github.com/rust-lang/rust/blob/2feb91181882e525e698c4543063f4d0296fcf91/library/std/src/sys/io/mod.rs#L44
214- // spell-checker:ignore espidf
215- const DEFAULT_BUF_SIZE : usize = if cfg ! ( target_os = "espidf" ) {
214+ const FIRST_BUF_SIZE : usize = if cfg ! ( target_os = "espidf" ) {
216215 512
217216 } else {
218217 8 * 1024
219218 } ;
220-
221- let mut buffer = [ 0u8 ; DEFAULT_BUF_SIZE ] ;
219+ let mut buffer = [ 0u8 ; FIRST_BUF_SIZE ] ;
222220 let mut len = 0 ;
221+ match input. read ( & mut buffer) {
222+ Ok ( 0 ) => return Ok ( 0 ) ,
223+ Ok ( bytes_count) => {
224+ output. write_all ( & buffer[ 0 ..bytes_count] ) ?;
225+ len = bytes_count;
226+ if bytes_count < FIRST_BUF_SIZE {
227+ // flush the buffer to comply with POSIX requirement that
228+ // `tee` does not buffer the input.
229+ output. flush ( ) ?;
230+ return Ok ( len) ;
231+ }
232+ }
233+ Err ( e) if e. kind ( ) == ErrorKind :: Interrupted => ( ) ,
234+ Err ( e) => return Err ( e) ,
235+ }
223236
237+ // but optimize buffer size also for large file
238+ let mut buffer = vec ! [ 0u8 ; 4 * FIRST_BUF_SIZE ] ; //stack array makes code path for smaller file slower
224239 loop {
225240 match input. read ( & mut buffer) {
226241 Ok ( 0 ) => return Ok ( len) , // end of file
0 commit comments