Skip to content

Commit

Permalink
refactored readrng to uucore
Browse files Browse the repository at this point in the history
* new feature: rand_read
  • Loading branch information
f8ith committed Dec 27, 2024
1 parent ff50a37 commit 73d493c
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 43 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/uu/shred/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ path = "src/shred.rs"
[dependencies]
clap = { workspace = true }
rand = { workspace = true }
uucore = { workspace = true }
uucore = { workspace = true, features = ["rand-read"] }
libc = { workspace = true }

[[bin]]
Expand Down
27 changes: 26 additions & 1 deletion src/uu/shred/src/shred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::path::{Path, PathBuf};
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::parse_size::parse_size_u64;
use uucore::rand_read::{ReadRng, WrappedRng};
use uucore::shortcut_value_parser::ShortcutValueParser;
use uucore::{format_usage, help_about, help_section, help_usage, show_error, show_if_err};

Expand All @@ -34,6 +35,7 @@ pub mod options {
pub const VERBOSE: &str = "verbose";
pub const EXACT: &str = "exact";
pub const ZERO: &str = "zero";
pub const RANDOM_SOURCE: &str = "random-source";

pub mod remove {
pub const UNLINK: &str = "unlink";
Expand Down Expand Up @@ -261,6 +263,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let exact = matches.get_flag(options::EXACT) || size.is_some();
let zero = matches.get_flag(options::ZERO);
let verbose = matches.get_flag(options::VERBOSE);
let random_source = matches
.get_one::<String>(options::RANDOM_SOURCE)
.map(String::from);

for path_str in matches.get_many::<String>(options::FILE).unwrap() {
show_if_err!(wipe_file(
Expand All @@ -272,6 +277,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
zero,
verbose,
force,
&random_source
));
}
Ok(())
Expand Down Expand Up @@ -357,6 +363,13 @@ pub fn uu_app() -> Command {
.action(ArgAction::Append)
.value_hint(clap::ValueHint::FilePath),
)
.arg(
Arg::new(options::RANDOM_SOURCE)
.long(options::RANDOM_SOURCE)
.value_name("FILE")
.help("get random bytes from FILE")
.value_hint(clap::ValueHint::FilePath),
)
}

fn get_size(size_str_opt: Option<String>) -> Option<u64> {
Expand Down Expand Up @@ -392,6 +405,7 @@ fn wipe_file(
zero: bool,
verbose: bool,
force: bool,
random_source: &Option<String>,
) -> UResult<()> {
// Get these potential errors out of the way first
let path = Path::new(path_str);
Expand Down Expand Up @@ -452,7 +466,17 @@ fn wipe_file(
for pattern in PATTERNS.into_iter().take(remainder) {
pass_sequence.push(PassType::Pattern(pattern));
}
let mut rng = rand::thread_rng();

let mut rng = match random_source {
Some(r) => {
let file = File::open(&r[..]).map_err_context(|| {
format!("failed to open random source {}", r.quote())
})?;
WrappedRng::RngFile(ReadRng::new(file))
}
None => WrappedRng::RngDefault(rand::thread_rng()),
};

pass_sequence.shuffle(&mut rng); // randomize the order of application

let n_random = 3 + n_passes / 10; // Minimum 3 random passes; ratio of 10 after
Expand Down Expand Up @@ -501,6 +525,7 @@ fn wipe_file(
do_remove(path, path_str, verbose, remove_method)
.map_err_context(|| format!("{}: failed to remove file", path.maybe_quote()))?;
}

Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion src/uu/shuf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ clap = { workspace = true }
memchr = { workspace = true }
rand = { workspace = true }
rand_core = { workspace = true }
uucore = { workspace = true }
uucore = { workspace = true, features = ["rand-read"] }

[[bin]]
name = "shuf"
Expand Down
42 changes: 3 additions & 39 deletions src/uu/shuf/src/shuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@
use clap::{crate_version, Arg, ArgAction, Command};
use memchr::memchr_iter;
use rand::prelude::SliceRandom;
use rand::{Rng, RngCore};
use rand::Rng;
use std::collections::HashSet;
use std::fs::File;
use std::io::{stdin, stdout, BufReader, BufWriter, Error, Read, Write};
use std::ops::RangeInclusive;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::rand_read::{ReadRng, WrappedRng};
use uucore::{format_usage, help_about, help_usage};

mod rand_read_adapter;

enum Mode {
Default(String),
Echo(Vec<String>),
Expand Down Expand Up @@ -433,7 +432,7 @@ fn shuf_exec(input: &mut impl Shufable, opts: Options) -> UResult<()> {
Some(r) => {
let file = File::open(&r[..])
.map_err_context(|| format!("failed to open random source {}", r.quote()))?;
WrappedRng::RngFile(rand_read_adapter::ReadRng::new(file))
WrappedRng::RngFile(ReadRng::new(file))
}
None => WrappedRng::RngDefault(rand::thread_rng()),
};
Expand Down Expand Up @@ -494,41 +493,6 @@ fn parse_head_count(headcounts: Vec<String>) -> Result<usize, String> {
Ok(result)
}

enum WrappedRng {
RngFile(rand_read_adapter::ReadRng<File>),
RngDefault(rand::rngs::ThreadRng),
}

impl RngCore for WrappedRng {
fn next_u32(&mut self) -> u32 {
match self {
Self::RngFile(r) => r.next_u32(),
Self::RngDefault(r) => r.next_u32(),
}
}

fn next_u64(&mut self) -> u64 {
match self {
Self::RngFile(r) => r.next_u64(),
Self::RngDefault(r) => r.next_u64(),
}
}

fn fill_bytes(&mut self, dest: &mut [u8]) {
match self {
Self::RngFile(r) => r.fill_bytes(dest),
Self::RngDefault(r) => r.fill_bytes(dest),
}
}

fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
match self {
Self::RngFile(r) => r.try_fill_bytes(dest),
Self::RngDefault(r) => r.try_fill_bytes(dest),
}
}
}

#[cfg(test)]
// Since the computed value is a bool, it is more readable to write the expected value out:
#[allow(clippy::bool_assert_comparison)]
Expand Down
3 changes: 3 additions & 0 deletions src/uucore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ dunce = { version = "1.0.4", optional = true }
wild = "2.2.1"
glob = { workspace = true }
lazy_static = "1.4.0"
rand = { workspace = true }
rand_core = { workspace = true }
# * optional
itertools = { workspace = true, optional = true }
thiserror = { workspace = true, optional = true }
Expand Down Expand Up @@ -92,6 +94,7 @@ pipes = []
process = ["libc"]
proc-info = ["tty", "walkdir"]
quoting-style = []
rand-read = []
ranges = []
ringbuffer = []
signals = []
Expand Down
2 changes: 2 additions & 0 deletions src/uucore/src/lib/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub mod fsext;
pub mod lines;
#[cfg(feature = "quoting-style")]
pub mod quoting_style;
#[cfg(feature = "rand-read")]
pub mod rand_read;
#[cfg(feature = "ranges")]
pub mod ranges;
#[cfg(feature = "ringbuffer")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

//! A wrapper around any Read to treat it as an RNG.
use std::fmt;
use std::io::Read;
use std::{fmt, fs::File};

use rand_core::{impls, Error, RngCore};

Expand Down Expand Up @@ -89,6 +89,41 @@ impl std::error::Error for ReadError {
}
}

pub enum WrappedRng {
RngFile(ReadRng<File>),
RngDefault(rand::rngs::ThreadRng),
}

impl RngCore for WrappedRng {
fn next_u32(&mut self) -> u32 {
match self {
Self::RngFile(r) => r.next_u32(),
Self::RngDefault(r) => r.next_u32(),
}
}

fn next_u64(&mut self) -> u64 {
match self {
Self::RngFile(r) => r.next_u64(),
Self::RngDefault(r) => r.next_u64(),
}
}

fn fill_bytes(&mut self, dest: &mut [u8]) {
match self {
Self::RngFile(r) => r.fill_bytes(dest),
Self::RngDefault(r) => r.fill_bytes(dest),
}
}

fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
match self {
Self::RngFile(r) => r.try_fill_bytes(dest),
Self::RngDefault(r) => r.try_fill_bytes(dest),
}
}
}

#[cfg(test)]
mod test {
use std::println;
Expand Down
2 changes: 2 additions & 0 deletions src/uucore/src/lib/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ pub use crate::features::fs;
pub use crate::features::lines;
#[cfg(feature = "quoting-style")]
pub use crate::features::quoting_style;
#[cfg(feature = "rand-read")]
pub use crate::features::rand_read;
#[cfg(feature = "ranges")]
pub use crate::features::ranges;
#[cfg(feature = "ringbuffer")]
Expand Down

0 comments on commit 73d493c

Please sign in to comment.