mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
mkdir: move to a config approach for the functions
This commit is contained in:
parent
d41c0ceb53
commit
b874d90345
1 changed files with 44 additions and 69 deletions
|
@ -33,6 +33,24 @@ mod options {
|
|||
pub const CONTEXT: &str = "context";
|
||||
}
|
||||
|
||||
/// Configuration for directory creation.
|
||||
pub struct Config<'a> {
|
||||
/// Create parent directories as needed.
|
||||
pub recursive: bool,
|
||||
|
||||
/// File permissions (octal).
|
||||
pub mode: u32,
|
||||
|
||||
/// Print message for each created directory.
|
||||
pub verbose: bool,
|
||||
|
||||
/// Set SELinux security context.
|
||||
pub set_selinux_context: bool,
|
||||
|
||||
/// Specific SELinux context.
|
||||
pub context: Option<&'a String>,
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_mode(_matches: &ArgMatches, _mode_had_minus_prefix: bool) -> Result<u32, String> {
|
||||
Ok(DEFAULT_PERM)
|
||||
|
@ -98,14 +116,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
let context = matches.get_one::<String>(options::CONTEXT);
|
||||
|
||||
match get_mode(&matches, mode_had_minus_prefix) {
|
||||
Ok(mode) => exec(
|
||||
dirs,
|
||||
recursive,
|
||||
mode,
|
||||
verbose,
|
||||
set_selinux_context || context.is_some(),
|
||||
context,
|
||||
),
|
||||
Ok(mode) => {
|
||||
let config = Config {
|
||||
recursive,
|
||||
mode,
|
||||
verbose,
|
||||
set_selinux_context: set_selinux_context || context.is_some(),
|
||||
context,
|
||||
};
|
||||
exec(dirs, &config)
|
||||
}
|
||||
Err(f) => Err(USimpleError::new(1, f)),
|
||||
}
|
||||
}
|
||||
|
@ -159,26 +179,12 @@ pub fn uu_app() -> Command {
|
|||
/**
|
||||
* Create the list of new directories
|
||||
*/
|
||||
fn exec(
|
||||
dirs: ValuesRef<OsString>,
|
||||
recursive: bool,
|
||||
mode: u32,
|
||||
verbose: bool,
|
||||
set_selinux_context: bool,
|
||||
context: Option<&String>,
|
||||
) -> UResult<()> {
|
||||
fn exec(dirs: ValuesRef<OsString>, config: &Config) -> UResult<()> {
|
||||
for dir in dirs {
|
||||
let path_buf = PathBuf::from(dir);
|
||||
let path = path_buf.as_path();
|
||||
|
||||
show_if_err!(mkdir(
|
||||
path,
|
||||
recursive,
|
||||
mode,
|
||||
verbose,
|
||||
set_selinux_context,
|
||||
context
|
||||
));
|
||||
show_if_err!(mkdir(path, config));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -196,14 +202,7 @@ fn exec(
|
|||
///
|
||||
/// To match the GNU behavior, a path with the last directory being a single dot
|
||||
/// (like `some/path/to/.`) is created (with the dot stripped).
|
||||
pub fn mkdir(
|
||||
path: &Path,
|
||||
recursive: bool,
|
||||
mode: u32,
|
||||
verbose: bool,
|
||||
set_selinux_context: bool,
|
||||
context: Option<&String>,
|
||||
) -> UResult<()> {
|
||||
pub fn mkdir(path: &Path, config: &Config) -> UResult<()> {
|
||||
if path.as_os_str().is_empty() {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
|
@ -216,15 +215,7 @@ pub fn mkdir(
|
|||
// std::fs::create_dir("foo/."); fails in pure Rust
|
||||
let path_buf = dir_strip_dot_for_creation(path);
|
||||
let path = path_buf.as_path();
|
||||
create_dir(
|
||||
path,
|
||||
recursive,
|
||||
verbose,
|
||||
false,
|
||||
mode,
|
||||
set_selinux_context,
|
||||
context,
|
||||
)
|
||||
create_dir(path, false, config)
|
||||
}
|
||||
|
||||
#[cfg(any(unix, target_os = "redox"))]
|
||||
|
@ -245,17 +236,9 @@ fn chmod(_path: &Path, _mode: u32) -> UResult<()> {
|
|||
// Return true if the directory at `path` has been created by this call.
|
||||
// `is_parent` argument is not used on windows
|
||||
#[allow(unused_variables)]
|
||||
fn create_dir(
|
||||
path: &Path,
|
||||
recursive: bool,
|
||||
verbose: bool,
|
||||
is_parent: bool,
|
||||
mode: u32,
|
||||
set_selinux_context: bool,
|
||||
context: Option<&String>,
|
||||
) -> UResult<()> {
|
||||
fn create_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<()> {
|
||||
let path_exists = path.exists();
|
||||
if path_exists && !recursive {
|
||||
if path_exists && !config.recursive {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("{}: File exists", path.display()),
|
||||
|
@ -265,17 +248,9 @@ fn create_dir(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
if recursive {
|
||||
if config.recursive {
|
||||
match path.parent() {
|
||||
Some(p) => create_dir(
|
||||
p,
|
||||
recursive,
|
||||
verbose,
|
||||
true,
|
||||
mode,
|
||||
set_selinux_context,
|
||||
context,
|
||||
)?,
|
||||
Some(p) => create_dir(p, true, config)?,
|
||||
None => {
|
||||
USimpleError::new(1, "failed to create whole tree");
|
||||
}
|
||||
|
@ -284,7 +259,7 @@ fn create_dir(
|
|||
|
||||
match std::fs::create_dir(path) {
|
||||
Ok(()) => {
|
||||
if verbose {
|
||||
if config.verbose {
|
||||
println!(
|
||||
"{}: created directory {}",
|
||||
uucore::util_name(),
|
||||
|
@ -294,7 +269,7 @@ fn create_dir(
|
|||
|
||||
#[cfg(all(unix, target_os = "linux"))]
|
||||
let new_mode = if path_exists {
|
||||
mode
|
||||
config.mode
|
||||
} else {
|
||||
// TODO: Make this macos and freebsd compatible by creating a function to get permission bits from
|
||||
// acl in extended attributes
|
||||
|
@ -303,24 +278,24 @@ fn create_dir(
|
|||
if is_parent {
|
||||
(!mode::get_umask() & 0o777) | 0o300 | acl_perm_bits
|
||||
} else {
|
||||
mode | acl_perm_bits
|
||||
config.mode | acl_perm_bits
|
||||
}
|
||||
};
|
||||
#[cfg(all(unix, not(target_os = "linux")))]
|
||||
let new_mode = if is_parent {
|
||||
(!mode::get_umask() & 0o777) | 0o300
|
||||
} else {
|
||||
mode
|
||||
config.mode
|
||||
};
|
||||
#[cfg(windows)]
|
||||
let new_mode = mode;
|
||||
let new_mode = config.mode;
|
||||
|
||||
chmod(path, new_mode)?;
|
||||
|
||||
// Apply SELinux context if requested
|
||||
#[cfg(target_os = "linux")]
|
||||
if set_selinux_context {
|
||||
if let Err(e) = uucore::selinux_support::set_selinux_security_context(path, context)
|
||||
#[cfg(feature = "selinux")]
|
||||
if config.set_selinux_context && uucore::selinux::check_selinux_enabled().is_ok() {
|
||||
if let Err(e) = uucore::selinux::set_selinux_security_context(path, config.context)
|
||||
{
|
||||
let _ = std::fs::remove_dir(path);
|
||||
return Err(USimpleError::new(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue