mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
mkdir: adapt to standardized error handling
This commit is contained in:
parent
e4eac825fb
commit
8c5052fcb7
1 changed files with 48 additions and 78 deletions
|
@ -8,25 +8,26 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
|
use clap::OsValues;
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use uucore::error::{FromIo, UResult, USimpleError};
|
||||||
|
|
||||||
static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist";
|
static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist";
|
||||||
static OPT_MODE: &str = "mode";
|
mod options {
|
||||||
static OPT_PARENTS: &str = "parents";
|
pub const MODE: &str = "mode";
|
||||||
static OPT_VERBOSE: &str = "verbose";
|
pub const PARENTS: &str = "parents";
|
||||||
|
pub const VERBOSE: &str = "verbose";
|
||||||
static ARG_DIRS: &str = "dirs";
|
pub const DIRS: &str = "dirs";
|
||||||
|
}
|
||||||
|
|
||||||
fn get_usage() -> String {
|
fn get_usage() -> String {
|
||||||
format!("{0} [OPTION]... [USER]", executable!())
|
format!("{0} [OPTION]... [USER]", executable!())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[uucore_procs::gen_uumain]
|
||||||
* Handles option parsing
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
*/
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
|
||||||
let usage = get_usage();
|
let usage = get_usage();
|
||||||
|
|
||||||
// Linux-specific options, not implemented
|
// Linux-specific options, not implemented
|
||||||
|
@ -34,26 +35,16 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
// " of each created directory to CTX"),
|
// " of each created directory to CTX"),
|
||||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||||
|
|
||||||
let dirs: Vec<String> = matches
|
let dirs = matches.values_of_os(options::DIRS).unwrap_or_default();
|
||||||
.values_of(ARG_DIRS)
|
let verbose = matches.is_present(options::VERBOSE);
|
||||||
.map(|v| v.map(ToString::to_string).collect())
|
let recursive = matches.is_present(options::PARENTS);
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let verbose = matches.is_present(OPT_VERBOSE);
|
|
||||||
let recursive = matches.is_present(OPT_PARENTS);
|
|
||||||
|
|
||||||
// Translate a ~str in octal form to u16, default to 755
|
// Translate a ~str in octal form to u16, default to 755
|
||||||
// Not tested on Windows
|
// Not tested on Windows
|
||||||
let mode_match = matches.value_of(OPT_MODE);
|
let mode: u16 = match matches.value_of(options::MODE) {
|
||||||
let mode: u16 = match mode_match {
|
Some(m) => u16::from_str_radix(m, 8)
|
||||||
Some(m) => {
|
.map_err(|_| USimpleError::new(1, format!("invalid mode '{}'", m)))?,
|
||||||
let res: Option<u16> = u16::from_str_radix(m, 8).ok();
|
None => 0o755_u16,
|
||||||
match res {
|
|
||||||
Some(r) => r,
|
|
||||||
_ => crash!(1, "no mode given"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => 0o755_u16,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
exec(dirs, recursive, mode, verbose)
|
exec(dirs, recursive, mode, verbose)
|
||||||
|
@ -64,27 +55,27 @@ pub fn uu_app() -> App<'static, 'static> {
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
.about(ABOUT)
|
.about(ABOUT)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_MODE)
|
Arg::with_name(options::MODE)
|
||||||
.short("m")
|
.short("m")
|
||||||
.long(OPT_MODE)
|
.long(options::MODE)
|
||||||
.help("set file mode (not implemented on windows)")
|
.help("set file mode (not implemented on windows)")
|
||||||
.default_value("755"),
|
.default_value("755"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_PARENTS)
|
Arg::with_name(options::PARENTS)
|
||||||
.short("p")
|
.short("p")
|
||||||
.long(OPT_PARENTS)
|
.long(options::PARENTS)
|
||||||
.alias("parent")
|
.alias("parent")
|
||||||
.help("make parent directories as needed"),
|
.help("make parent directories as needed"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_VERBOSE)
|
Arg::with_name(options::VERBOSE)
|
||||||
.short("v")
|
.short("v")
|
||||||
.long(OPT_VERBOSE)
|
.long(options::VERBOSE)
|
||||||
.help("print a message for each printed directory"),
|
.help("print a message for each printed directory"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(ARG_DIRS)
|
Arg::with_name(options::DIRS)
|
||||||
.multiple(true)
|
.multiple(true)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.min_values(1),
|
.min_values(1),
|
||||||
|
@ -94,64 +85,43 @@ pub fn uu_app() -> App<'static, 'static> {
|
||||||
/**
|
/**
|
||||||
* Create the list of new directories
|
* Create the list of new directories
|
||||||
*/
|
*/
|
||||||
fn exec(dirs: Vec<String>, recursive: bool, mode: u16, verbose: bool) -> i32 {
|
fn exec(dirs: OsValues, recursive: bool, mode: u16, verbose: bool) -> UResult<()> {
|
||||||
let mut status = 0;
|
for dir in dirs {
|
||||||
let empty = Path::new("");
|
|
||||||
for dir in &dirs {
|
|
||||||
let path = Path::new(dir);
|
let path = Path::new(dir);
|
||||||
if !recursive {
|
show_if_err!(mkdir(path, recursive, mode, verbose));
|
||||||
if let Some(parent) = path.parent() {
|
|
||||||
if parent != empty && !parent.exists() {
|
|
||||||
show_error!(
|
|
||||||
"cannot create directory '{}': No such file or directory",
|
|
||||||
path.display()
|
|
||||||
);
|
|
||||||
status = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
status |= mkdir(path, recursive, mode, verbose);
|
|
||||||
}
|
}
|
||||||
status
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fn mkdir(path: &Path, recursive: bool, mode: u16, verbose: bool) -> UResult<()> {
|
||||||
* Wrapper to catch errors, return 1 if failed
|
|
||||||
*/
|
|
||||||
fn mkdir(path: &Path, recursive: bool, mode: u16, verbose: bool) -> i32 {
|
|
||||||
let create_dir = if recursive {
|
let create_dir = if recursive {
|
||||||
fs::create_dir_all
|
fs::create_dir_all
|
||||||
} else {
|
} else {
|
||||||
fs::create_dir
|
fs::create_dir
|
||||||
};
|
};
|
||||||
if let Err(e) = create_dir(path) {
|
|
||||||
show_error!("{}: {}", path.display(), e.to_string());
|
create_dir(path).map_err_context(|| format!("cannot create directory '{}'", path.display()))?;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if verbose {
|
if verbose {
|
||||||
println!("{}: created directory '{}'", executable!(), path.display());
|
println!("{}: created directory '{}'", executable!(), path.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(unix, target_os = "redox"))]
|
|
||||||
fn chmod(path: &Path, mode: u16) -> i32 {
|
|
||||||
use std::fs::{set_permissions, Permissions};
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
|
|
||||||
let mode = Permissions::from_mode(u32::from(mode));
|
|
||||||
|
|
||||||
if let Err(err) = set_permissions(path, mode) {
|
|
||||||
show_error!("{}: {}", path.display(), err);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
0
|
|
||||||
}
|
|
||||||
#[cfg(windows)]
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn chmod(path: &Path, mode: u16) -> i32 {
|
|
||||||
// chmod on Windows only sets the readonly flag, which isn't even honored on directories
|
|
||||||
0
|
|
||||||
}
|
|
||||||
chmod(path, mode)
|
chmod(path, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(unix, target_os = "redox"))]
|
||||||
|
fn chmod(path: &Path, mode: u16) -> UResult<()> {
|
||||||
|
use std::fs::{set_permissions, Permissions};
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
|
let mode = Permissions::from_mode(u32::from(mode));
|
||||||
|
|
||||||
|
set_permissions(path, mode)
|
||||||
|
.map_err_context(|| format!("cannot set permissions '{}'", path.display()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn chmod(_path: &Path, _mode: u16) -> UResult<()> {
|
||||||
|
// chmod on Windows only sets the readonly flag, which isn't even honored on directories
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue