Skip to content

Commit

Permalink
unset direct mode also for read if needed
Browse files Browse the repository at this point in the history
  • Loading branch information
cre4ture committed Mar 18, 2024
1 parent 41bb74f commit 6065e55
Showing 1 changed file with 30 additions and 9 deletions.
39 changes: 30 additions & 9 deletions src/uu/dd/src/dd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ enum Source {
}

impl Source {
fn unset_direct(&mut self) -> io::Result<()> {
if let Self::File(f) = self {

Check warning on line 186 in src/uu/dd/src/dd.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/dd/src/dd.rs#L185-L186

Added lines #L185 - L186 were not covered by tests
unset_direct(f)?
}
Ok(())
}

Check warning on line 190 in src/uu/dd/src/dd.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/dd/src/dd.rs#L189-L190

Added lines #L189 - L190 were not covered by tests

/// Create a source from stdin using its raw file descriptor.
///
/// This returns an instance of the `Source::StdinFile` variant,
Expand Down Expand Up @@ -397,6 +404,17 @@ impl<'a> Read for Input<'a> {
let mut base_idx = 0;
let target_len = buf.len();
loop {
if self.settings.iflags.direct {
let remaining = target_len - base_idx;
if remaining < self.settings.ibs {
// when previous read was interrupted (e.g. due to OS signal)
// OR when previous read was short (e.g. due to End of File)
// we need to do a irregular read.
// we can do that by disabling direct read.
self.src.unset_direct()?;
}
}

match self.src.read(&mut buf[base_idx..]) {
Ok(0) => return Ok(base_idx),
Ok(rlen) if self.settings.iflags.fullblock => {
Expand Down Expand Up @@ -537,16 +555,9 @@ enum Dest {

impl Dest {
fn unset_direct(&mut self) -> io::Result<()> {
match self {
#[cfg(any(target_os = "linux", target_os = "android"))]
Self::File(f, _d) => {
let mut mode = OFlag::from_bits_retain(fcntl(f.as_raw_fd(), FcntlArg::F_GETFL)?);
mode.remove(OFlag::O_DIRECT);
nix::fcntl::fcntl(f.as_raw_fd(), FcntlArg::F_SETFL(mode))?;
}
_ => {}
if let Self::File(f, _d) = self {
unset_direct(f)?
}

Ok(())
}

Expand Down Expand Up @@ -649,6 +660,16 @@ impl Dest {
}
}

fn unset_direct(_f: &mut File) -> io::Result<()> {
#[cfg(any(target_os = "linux", target_os = "android"))]
{
let mut mode = OFlag::from_bits_retain(fcntl(_f.as_raw_fd(), FcntlArg::F_GETFL)?);
mode.remove(OFlag::O_DIRECT);
nix::fcntl::fcntl(_f.as_raw_fd(), FcntlArg::F_SETFL(mode))?;
}
Ok(())
}

/// Decide whether the given buffer is all zeros.
fn is_sparse(buf: &[u8]) -> bool {
buf.iter().all(|&e| e == 0u8)
Expand Down

0 comments on commit 6065e55

Please sign in to comment.