diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 7cc4f73924d..b7561d6b590 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -30,7 +30,7 @@ use std::cmp; use std::env; use std::ffi::OsString; use std::fs::{File, OpenOptions}; -use std::io::{self, Read, Seek, SeekFrom, Stdout, Write}; +use std::io::{self, BufReader, Read, Seek, SeekFrom, Stdout, Write}; #[cfg(any(target_os = "linux", target_os = "android"))] use std::os::fd::AsFd; #[cfg(any(target_os = "linux", target_os = "android"))] @@ -230,10 +230,13 @@ impl Source { } } - fn skip(&mut self, n: u64) -> io::Result { + fn skip(&mut self, n: u64, ibs: usize) -> io::Result { match self { #[cfg(not(unix))] - Self::Stdin(stdin) => match io::copy(&mut stdin.take(n), &mut io::sink()) { + Self::Stdin(stdin) => match io::copy( + &mut BufReader::with_capacity(ibs, stdin.take(n)), + &mut io::sink(), + ) { Ok(m) if m < n => { show_error!( "{}", @@ -258,7 +261,10 @@ impl Source { return Ok(len); } } - match io::copy(&mut f.take(n), &mut io::sink()) { + match io::copy( + &mut BufReader::with_capacity(ibs, f.take(n)), + &mut io::sink(), + ) { Ok(m) if m < n => { show_error!( "{}", @@ -272,7 +278,10 @@ impl Source { } Self::File(f) => f.seek(SeekFrom::Current(n.try_into().unwrap())), #[cfg(unix)] - Self::Fifo(f) => io::copy(&mut f.take(n), &mut io::sink()), + Self::Fifo(f) => io::copy( + &mut BufReader::with_capacity(ibs, f.take(n)), + &mut io::sink(), + ), } } @@ -357,7 +366,7 @@ impl<'a> Input<'a> { } } if settings.skip > 0 { - src.skip(settings.skip)?; + src.skip(settings.skip, settings.ibs)?; } Ok(Self { src, settings }) } @@ -380,7 +389,7 @@ impl<'a> Input<'a> { let mut src = Source::File(src); if settings.skip > 0 { - src.skip(settings.skip)?; + src.skip(settings.skip, settings.ibs)?; } Ok(Self { src, settings }) } @@ -394,7 +403,7 @@ impl<'a> Input<'a> { opts.custom_flags(make_linux_iflags(&settings.iflags).unwrap_or(0)); let mut src = Source::Fifo(opts.open(filename)?); if settings.skip > 0 { - src.skip(settings.skip)?; + src.skip(settings.skip, settings.ibs)?; } Ok(Self { src, settings }) } @@ -611,7 +620,8 @@ impl Dest { } } - fn seek(&mut self, n: u64) -> io::Result { + #[cfg_attr(not(unix), allow(unused_variables))] + fn seek(&mut self, n: u64, obs: usize) -> io::Result { match self { Self::Stdout(stdout) => io::copy(&mut io::repeat(0).take(n), stdout), Self::File(f, _) => { @@ -633,7 +643,10 @@ impl Dest { #[cfg(unix)] Self::Fifo(f) => { // Seeking in a named pipe means *reading* from the pipe. - io::copy(&mut f.take(n), &mut io::sink()) + io::copy( + &mut BufReader::with_capacity(obs, f.take(n)), + &mut io::sink(), + ) } #[cfg(unix)] Self::Sink => Ok(0), @@ -798,7 +811,7 @@ impl<'a> Output<'a> { /// Instantiate this struct with stdout as a destination. fn new_stdout(settings: &'a Settings) -> UResult { let mut dst = Dest::Stdout(io::stdout()); - dst.seek(settings.seek) + dst.seek(settings.seek, settings.obs) .map_err_context(|| translate!("dd-error-write-error"))?; Ok(Self { dst, settings }) } @@ -846,7 +859,7 @@ impl<'a> Output<'a> { Density::Dense }; let mut dst = Dest::File(dst, density); - dst.seek(settings.seek) + dst.seek(settings.seek, settings.obs) .map_err_context(|| translate!("dd-error-failed-to-seek"))?; Ok(Self { dst, settings }) } @@ -876,7 +889,7 @@ impl<'a> Output<'a> { // file for reading. But then we need to close the file and // re-open it for writing. if settings.seek > 0 { - Dest::Fifo(File::open(filename)?).seek(settings.seek)?; + Dest::Fifo(File::open(filename)?).seek(settings.seek, settings.obs)?; } // If `count=0`, then we don't bother opening the file for // writing because that would cause this process to block