From d14b5843a3f42afa2d7f9e4a5e65ab51545231d0 Mon Sep 17 00:00:00 2001 From: Tyler Date: Thu, 17 Jun 2021 14:33:30 -0700 Subject: [PATCH] Implements libc file open flags (unix only) --- Cargo.lock | 1 + src/uu/dd/Cargo.toml | 1 + src/uu/dd/src/dd.rs | 136 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 132 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 779d4b99e..0e9bd8847 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1760,6 +1760,7 @@ dependencies = [ "gcd", "getopts", "hex-literal", + "libc", "md-5", "signal-hook", "uucore", diff --git a/src/uu/dd/Cargo.toml b/src/uu/dd/Cargo.toml index ce53439b2..e10fd7f07 100644 --- a/src/uu/dd/Cargo.toml +++ b/src/uu/dd/Cargo.toml @@ -20,6 +20,7 @@ debug_print = "1.0" # Probably best to keep this identical to the version of getopts in the uucore crate getopts = "<= 0.2.21" gcd = "2.0" +libc = "0.2" signal-hook = "0.3.9" uucore = { version=">=0.0.7", package="uucore", path="../../uucore" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 564e8804d..5eccf032a 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -35,6 +35,10 @@ use std::io::{ self, Read, Write, Seek, }; +#[cfg(unix)] +use libc; +#[cfg(unix)] +use std::os::unix::fs::OpenOptionsExt; use std::sync::{ Arc, atomic::AtomicUsize, mpsc, atomic::Ordering, }; @@ -250,6 +254,53 @@ impl Input } } +fn make_unix_iflags(oflags: &IFlags) -> Option +{ + let mut flag = 0; + + if oflags.direct + { + flag |= libc::O_DIRECT; + } + if oflags.directory + { + flag |= libc::O_DIRECTORY; + } + if oflags.dsync + { + flag |= libc::O_DSYNC; + } + if oflags.noatime + { + flag |= libc::O_NOATIME; + } + if oflags.noctty + { + flag |= libc::O_NOCTTY; + } + if oflags.nofollow + { + flag |= libc::O_NOFOLLOW; + } + if oflags.nonblock + { + flag |= libc::O_NONBLOCK; + } + if oflags.sync + { + flag |= libc::O_SYNC; + } + + if flag != 0 + { + Some(flag) + } + else + { + None + } +} + impl Input { fn new(matches: &getopts::Matches) -> Result> @@ -264,7 +315,21 @@ impl Input if let Some(fname) = matches.opt_str("if") { - let mut src = File::open(fname)?; + let mut src = + { + let mut opts = OpenOptions::new(); + opts.read(true); + + if cfg!(unix) + { + if let Some(libc_flags) = make_unix_iflags(&iflags) + { + opts.custom_flags(libc_flags); + } + } + + opts.open(fname)? + }; if let Some(amt) = skip { @@ -461,6 +526,53 @@ impl Output { } } +fn make_unix_oflags(oflags: &OFlags) -> Option +{ + let mut flag = 0; + + if oflags.direct + { + flag |= libc::O_DIRECT; + } + if oflags.directory + { + flag |= libc::O_DIRECTORY; + } + if oflags.dsync + { + flag |= libc::O_DSYNC; + } + if oflags.noatime + { + flag |= libc::O_NOATIME; + } + if oflags.noctty + { + flag |= libc::O_NOCTTY; + } + if oflags.nofollow + { + flag |= libc::O_NOFOLLOW; + } + if oflags.nonblock + { + flag |= libc::O_NONBLOCK; + } + if oflags.sync + { + flag |= libc::O_SYNC; + } + + if flag != 0 + { + Some(flag) + } + else + { + None + } +} + impl Output { fn new(matches: &getopts::Matches) -> Result> { @@ -471,11 +583,23 @@ impl Output { if let Some(fname) = matches.opt_str("of") { - let mut dst = OpenOptions::new() - .write(true) - .create(!cflags.nocreat) - .truncate(!cflags.notrunc) - .open(fname)?; + let mut dst = { + let mut opts = OpenOptions::new(); + opts.write(true) + .append(oflags.append) + .create_new(cflags.excl || !cflags.nocreat) + .truncate(!cflags.notrunc); + + if cfg!(unix) + { + if let Some(libc_flags) = make_unix_oflags(&oflags) + { + opts.custom_flags(libc_flags); + } + } + + opts.open(fname)? + }; if let Some(amt) = seek {