Skip to content

Commit 2f251f1

Browse files
committed
mkdir: move to a config approach for the functions
1 parent 1735887 commit 2f251f1

File tree

1 file changed

+43
-69
lines changed

1 file changed

+43
-69
lines changed

src/uu/mkdir/src/mkdir.rs

Lines changed: 43 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ mod options {
3333
pub const CONTEXT: &str = "context";
3434
}
3535

36+
/// Configuration for directory creation.
37+
pub struct Config<'a> {
38+
/// Create parent directories as needed.
39+
pub recursive: bool,
40+
41+
/// File permissions (octal).
42+
pub mode: u32,
43+
44+
/// Print message for each created directory.
45+
pub verbose: bool,
46+
47+
/// Set SELinux security context.
48+
pub set_selinux_context: bool,
49+
50+
/// Specific SELinux context.
51+
pub context: Option<&'a String>,
52+
}
3653
#[cfg(windows)]
3754
fn get_mode(_matches: &ArgMatches, _mode_had_minus_prefix: bool) -> Result<u32, String> {
3855
Ok(DEFAULT_PERM)
@@ -98,14 +115,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
98115
let context = matches.get_one::<String>(options::CONTEXT);
99116

100117
match get_mode(&matches, mode_had_minus_prefix) {
101-
Ok(mode) => exec(
102-
dirs,
103-
recursive,
104-
mode,
105-
verbose,
106-
set_selinux_context || context.is_some(),
107-
context,
108-
),
118+
Ok(mode) => {
119+
let config = Config {
120+
recursive,
121+
mode,
122+
verbose,
123+
set_selinux_context: set_selinux_context || context.is_some(),
124+
context,
125+
};
126+
exec(dirs, &config)
127+
}
109128
Err(f) => Err(USimpleError::new(1, f)),
110129
}
111130
}
@@ -159,26 +178,12 @@ pub fn uu_app() -> Command {
159178
/**
160179
* Create the list of new directories
161180
*/
162-
fn exec(
163-
dirs: ValuesRef<OsString>,
164-
recursive: bool,
165-
mode: u32,
166-
verbose: bool,
167-
set_selinux_context: bool,
168-
context: Option<&String>,
169-
) -> UResult<()> {
181+
fn exec(dirs: ValuesRef<OsString>, config: &Config) -> UResult<()> {
170182
for dir in dirs {
171183
let path_buf = PathBuf::from(dir);
172184
let path = path_buf.as_path();
173185

174-
show_if_err!(mkdir(
175-
path,
176-
recursive,
177-
mode,
178-
verbose,
179-
set_selinux_context,
180-
context
181-
));
186+
show_if_err!(mkdir(path, config));
182187
}
183188
Ok(())
184189
}
@@ -196,14 +201,7 @@ fn exec(
196201
///
197202
/// To match the GNU behavior, a path with the last directory being a single dot
198203
/// (like `some/path/to/.`) is created (with the dot stripped).
199-
pub fn mkdir(
200-
path: &Path,
201-
recursive: bool,
202-
mode: u32,
203-
verbose: bool,
204-
set_selinux_context: bool,
205-
context: Option<&String>,
206-
) -> UResult<()> {
204+
pub fn mkdir(path: &Path, config: &Config) -> UResult<()> {
207205
if path.as_os_str().is_empty() {
208206
return Err(USimpleError::new(
209207
1,
@@ -216,15 +214,7 @@ pub fn mkdir(
216214
// std::fs::create_dir("foo/."); fails in pure Rust
217215
let path_buf = dir_strip_dot_for_creation(path);
218216
let path = path_buf.as_path();
219-
create_dir(
220-
path,
221-
recursive,
222-
verbose,
223-
false,
224-
mode,
225-
set_selinux_context,
226-
context,
227-
)
217+
create_dir(path, false, config)
228218
}
229219

230220
#[cfg(any(unix, target_os = "redox"))]
@@ -245,17 +235,9 @@ fn chmod(_path: &Path, _mode: u32) -> UResult<()> {
245235
// Return true if the directory at `path` has been created by this call.
246236
// `is_parent` argument is not used on windows
247237
#[allow(unused_variables)]
248-
fn create_dir(
249-
path: &Path,
250-
recursive: bool,
251-
verbose: bool,
252-
is_parent: bool,
253-
mode: u32,
254-
set_selinux_context: bool,
255-
context: Option<&String>,
256-
) -> UResult<()> {
238+
fn create_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<()> {
257239
let path_exists = path.exists();
258-
if path_exists && !recursive {
240+
if path_exists && !config.recursive {
259241
return Err(USimpleError::new(
260242
1,
261243
format!("{}: File exists", path.display()),
@@ -265,17 +247,9 @@ fn create_dir(
265247
return Ok(());
266248
}
267249

268-
if recursive {
250+
if config.recursive {
269251
match path.parent() {
270-
Some(p) => create_dir(
271-
p,
272-
recursive,
273-
verbose,
274-
true,
275-
mode,
276-
set_selinux_context,
277-
context,
278-
)?,
252+
Some(p) => create_dir(p, true, config)?,
279253
None => {
280254
USimpleError::new(1, "failed to create whole tree");
281255
}
@@ -284,7 +258,7 @@ fn create_dir(
284258

285259
match std::fs::create_dir(path) {
286260
Ok(()) => {
287-
if verbose {
261+
if config.verbose {
288262
println!(
289263
"{}: created directory {}",
290264
uucore::util_name(),
@@ -294,7 +268,7 @@ fn create_dir(
294268

295269
#[cfg(all(unix, target_os = "linux"))]
296270
let new_mode = if path_exists {
297-
mode
271+
config.mode
298272
} else {
299273
// TODO: Make this macos and freebsd compatible by creating a function to get permission bits from
300274
// acl in extended attributes
@@ -303,24 +277,24 @@ fn create_dir(
303277
if is_parent {
304278
(!mode::get_umask() & 0o777) | 0o300 | acl_perm_bits
305279
} else {
306-
mode | acl_perm_bits
280+
config.mode | acl_perm_bits
307281
}
308282
};
309283
#[cfg(all(unix, not(target_os = "linux")))]
310284
let new_mode = if is_parent {
311285
(!mode::get_umask() & 0o777) | 0o300
312286
} else {
313-
mode
287+
config.mode
314288
};
315289
#[cfg(windows)]
316-
let new_mode = mode;
290+
let new_mode = config.mode;
317291

318292
chmod(path, new_mode)?;
319293

320294
// Apply SELinux context if requested
321-
#[cfg(target_os = "linux")]
322-
if set_selinux_context {
323-
if let Err(e) = uucore::selinux_support::set_selinux_security_context(path, context)
295+
#[cfg(feature = "selinux")]
296+
if config.set_selinux_context {
297+
if let Err(e) = uucore::selinux::set_selinux_security_context(path, config.context)
324298
{
325299
return Err(USimpleError::new(
326300
1,

0 commit comments

Comments
 (0)