mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
shred: return UResult from uumain() function
This commit is contained in:
parent
4ae838a8b2
commit
e9093681a5
1 changed files with 32 additions and 56 deletions
|
@ -19,6 +19,7 @@ use std::io::prelude::*;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
|
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
|
||||||
use uucore::{util_name, InvalidEncodingHandling};
|
use uucore::{util_name, InvalidEncodingHandling};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -266,7 +267,8 @@ pub mod options {
|
||||||
pub const ZERO: &str = "zero";
|
pub const ZERO: &str = "zero";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args
|
let args = args
|
||||||
.collect_str(InvalidEncodingHandling::Ignore)
|
.collect_str(InvalidEncodingHandling::Ignore)
|
||||||
.accept_any();
|
.accept_any();
|
||||||
|
@ -277,20 +279,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
|
|
||||||
let matches = app.get_matches_from(args);
|
let matches = app.get_matches_from(args);
|
||||||
|
|
||||||
let mut errs: Vec<String> = vec![];
|
|
||||||
|
|
||||||
if !matches.is_present(options::FILE) {
|
if !matches.is_present(options::FILE) {
|
||||||
show_error!("Missing an argument");
|
return Err(UUsageError::new(1, "missing file operand"));
|
||||||
show_error!("For help, try '{} --help'", uucore::execution_phrase());
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let iterations = match matches.value_of(options::ITERATIONS) {
|
let iterations = match matches.value_of(options::ITERATIONS) {
|
||||||
Some(s) => match s.parse::<usize>() {
|
Some(s) => match s.parse::<usize>() {
|
||||||
Ok(u) => u,
|
Ok(u) => u,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
errs.push(format!("invalid number of passes: {}", s.quote()));
|
return Err(USimpleError::new(
|
||||||
0
|
1,
|
||||||
|
format!("invalid number of passes: {}", s.quote()),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
|
@ -313,21 +313,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let zero = matches.is_present(options::ZERO);
|
let zero = matches.is_present(options::ZERO);
|
||||||
let verbose = matches.is_present(options::VERBOSE);
|
let verbose = matches.is_present(options::VERBOSE);
|
||||||
|
|
||||||
if !errs.is_empty() {
|
|
||||||
show_error!("Invalid arguments supplied.");
|
|
||||||
for message in errs {
|
|
||||||
show_error!("{}", message);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for path_str in matches.values_of(options::FILE).unwrap() {
|
for path_str in matches.values_of(options::FILE).unwrap() {
|
||||||
wipe_file(
|
show_if_err!(wipe_file(
|
||||||
path_str, iterations, remove, size, exact, zero, verbose, force,
|
path_str, iterations, remove, size, exact, zero, verbose, force,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app() -> App<'static, 'static> {
|
pub fn uu_app() -> App<'static, 'static> {
|
||||||
|
@ -452,34 +443,28 @@ fn wipe_file(
|
||||||
zero: bool,
|
zero: bool,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
force: bool,
|
force: bool,
|
||||||
) {
|
) -> UResult<()> {
|
||||||
// Get these potential errors out of the way first
|
// Get these potential errors out of the way first
|
||||||
let path: &Path = Path::new(path_str);
|
let path: &Path = Path::new(path_str);
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
show_error!("{}: No such file or directory", path.maybe_quote());
|
return Err(USimpleError::new(
|
||||||
return;
|
1,
|
||||||
|
format!("{}: No such file or directory", path.maybe_quote()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if !path.is_file() {
|
if !path.is_file() {
|
||||||
show_error!("{}: Not a file", path.maybe_quote());
|
return Err(USimpleError::new(
|
||||||
return;
|
1,
|
||||||
|
format!("{}: Not a file", path.maybe_quote()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If force is true, set file permissions to not-readonly.
|
// If force is true, set file permissions to not-readonly.
|
||||||
if force {
|
if force {
|
||||||
let metadata = match fs::metadata(path) {
|
let metadata = fs::metadata(path).map_err_context(String::new)?;
|
||||||
Ok(m) => m,
|
|
||||||
Err(e) => {
|
|
||||||
show_error!("{}", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut perms = metadata.permissions();
|
let mut perms = metadata.permissions();
|
||||||
perms.set_readonly(false);
|
perms.set_readonly(false);
|
||||||
if let Err(e) = fs::set_permissions(path, perms) {
|
fs::set_permissions(path, perms).map_err_context(String::new)?;
|
||||||
show_error!("{}", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill up our pass sequence
|
// Fill up our pass sequence
|
||||||
|
@ -521,13 +506,11 @@ fn wipe_file(
|
||||||
|
|
||||||
{
|
{
|
||||||
let total_passes: usize = pass_sequence.len();
|
let total_passes: usize = pass_sequence.len();
|
||||||
let mut file: File = match OpenOptions::new().write(true).truncate(false).open(path) {
|
let mut file: File = OpenOptions::new()
|
||||||
Ok(f) => f,
|
.write(true)
|
||||||
Err(e) => {
|
.truncate(false)
|
||||||
show_error!("{}: failed to open for writing: {}", path.maybe_quote(), e);
|
.open(path)
|
||||||
return;
|
.map_err_context(|| format!("{}: failed to open for writing", path.maybe_quote()))?;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE: it does not really matter what we set for total_bytes and gen_type here, so just
|
// NOTE: it does not really matter what we set for total_bytes and gen_type here, so just
|
||||||
// use bogus values
|
// use bogus values
|
||||||
|
@ -557,24 +540,17 @@ fn wipe_file(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// size is an optional argument for exactly how many bytes we want to shred
|
// size is an optional argument for exactly how many bytes we want to shred
|
||||||
match do_pass(&mut file, path, &mut generator, *pass_type, size) {
|
show_if_err!(do_pass(&mut file, path, &mut generator, *pass_type, size)
|
||||||
Ok(_) => {}
|
.map_err_context(|| format!("{}: File write pass failed", path.maybe_quote())));
|
||||||
Err(e) => {
|
|
||||||
show_error!("{}: File write pass failed: {}", path.maybe_quote(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Ignore failed writes; just keep trying
|
// Ignore failed writes; just keep trying
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if remove {
|
if remove {
|
||||||
match do_remove(path, path_str, verbose) {
|
do_remove(path, path_str, verbose)
|
||||||
Ok(_) => {}
|
.map_err_context(|| format!("{}: failed to remove file", path.maybe_quote()))?;
|
||||||
Err(e) => {
|
|
||||||
show_error!("{}: failed to remove file: {}", path.maybe_quote(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_pass<'a>(
|
fn do_pass<'a>(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue