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