Skip to content

Commit f41eb4a

Browse files
committed
mkdir: move to a config approach for the functions
1 parent 691165a commit f41eb4a

File tree

1 file changed

+44
-69
lines changed

1 file changed

+44
-69
lines changed

src/uu/mkdir/src/mkdir.rs

Lines changed: 44 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ 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+
}
53+
3654
#[cfg(windows)]
3755
fn get_mode(_matches: &ArgMatches, _mode_had_minus_prefix: bool) -> Result<u32, String> {
3856
Ok(DEFAULT_PERM)
@@ -98,14 +116,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
98116
let context = matches.get_one::<String>(options::CONTEXT);
99117

100118
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-
),
119+
Ok(mode) => {
120+
let config = Config {
121+
recursive,
122+
mode,
123+
verbose,
124+
set_selinux_context: set_selinux_context || context.is_some(),
125+
context,
126+
};
127+
exec(dirs, &config)
128+
}
109129
Err(f) => Err(USimpleError::new(1, f)),
110130
}
111131
}
@@ -159,26 +179,12 @@ pub fn uu_app() -> Command {
159179
/**
160180
* Create the list of new directories
161181
*/
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<()> {
182+
fn exec(dirs: ValuesRef<OsString>, config: &Config) -> UResult<()> {
170183
for dir in dirs {
171184
let path_buf = PathBuf::from(dir);
172185
let path = path_buf.as_path();
173186

174-
show_if_err!(mkdir(
175-
path,
176-
recursive,
177-
mode,
178-
verbose,
179-
set_selinux_context,
180-
context
181-
));
187+
show_if_err!(mkdir(path, config));
182188
}
183189
Ok(())
184190
}
@@ -196,14 +202,7 @@ fn exec(
196202
///
197203
/// To match the GNU behavior, a path with the last directory being a single dot
198204
/// (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<()> {
205+
pub fn mkdir(path: &Path, config: &Config) -> UResult<()> {
207206
if path.as_os_str().is_empty() {
208207
return Err(USimpleError::new(
209208
1,
@@ -216,15 +215,7 @@ pub fn mkdir(
216215
// std::fs::create_dir("foo/."); fails in pure Rust
217216
let path_buf = dir_strip_dot_for_creation(path);
218217
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-
)
218+
create_dir(path, false, config)
228219
}
229220

230221
#[cfg(any(unix, target_os = "redox"))]
@@ -245,17 +236,9 @@ fn chmod(_path: &Path, _mode: u32) -> UResult<()> {
245236
// Return true if the directory at `path` has been created by this call.
246237
// `is_parent` argument is not used on windows
247238
#[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<()> {
239+
fn create_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<()> {
257240
let path_exists = path.exists();
258-
if path_exists && !recursive {
241+
if path_exists && !config.recursive {
259242
return Err(USimpleError::new(
260243
1,
261244
format!("{}: File exists", path.display()),
@@ -265,17 +248,9 @@ fn create_dir(
265248
return Ok(());
266249
}
267250

268-
if recursive {
251+
if config.recursive {
269252
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-
)?,
253+
Some(p) => create_dir(p, true, config)?,
279254
None => {
280255
USimpleError::new(1, "failed to create whole tree");
281256
}
@@ -284,7 +259,7 @@ fn create_dir(
284259

285260
match std::fs::create_dir(path) {
286261
Ok(()) => {
287-
if verbose {
262+
if config.verbose {
288263
println!(
289264
"{}: created directory {}",
290265
uucore::util_name(),
@@ -294,7 +269,7 @@ fn create_dir(
294269

295270
#[cfg(all(unix, target_os = "linux"))]
296271
let new_mode = if path_exists {
297-
mode
272+
config.mode
298273
} else {
299274
// TODO: Make this macos and freebsd compatible by creating a function to get permission bits from
300275
// acl in extended attributes
@@ -303,24 +278,24 @@ fn create_dir(
303278
if is_parent {
304279
(!mode::get_umask() & 0o777) | 0o300 | acl_perm_bits
305280
} else {
306-
mode | acl_perm_bits
281+
config.mode | acl_perm_bits
307282
}
308283
};
309284
#[cfg(all(unix, not(target_os = "linux")))]
310285
let new_mode = if is_parent {
311286
(!mode::get_umask() & 0o777) | 0o300
312287
} else {
313-
mode
288+
config.mode
314289
};
315290
#[cfg(windows)]
316-
let new_mode = mode;
291+
let new_mode = config.mode;
317292

318293
chmod(path, new_mode)?;
319294

320295
// 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)
296+
#[cfg(feature = "selinux")]
297+
if config.set_selinux_context {
298+
if let Err(e) = uucore::selinux::set_selinux_security_context(path, config.context)
324299
{
325300
return Err(USimpleError::new(
326301
1,

0 commit comments

Comments
 (0)