1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

Merge pull request #7825 from cakebaker/mknod_refactor_uumain

mknod: refactor `uumain`
This commit is contained in:
Sylvestre Ledru 2025-04-23 18:29:37 +02:00 committed by GitHub
commit 0125bbc2b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -42,6 +42,16 @@ enum FileType {
Fifo, Fifo,
} }
impl FileType {
fn as_mode(&self) -> mode_t {
match self {
Self::Block => S_IFBLK,
Self::Character => S_IFCHR,
Self::Fifo => S_IFIFO,
}
}
}
/// Configuration for directory creation. /// Configuration for directory creation.
pub struct Config<'a> { pub struct Config<'a> {
pub mode: mode_t, pub mode: mode_t,
@ -101,66 +111,49 @@ fn mknod(file_name: &str, config: Config) -> i32 {
pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uu_app().try_get_matches_from(args)?; let matches = uu_app().try_get_matches_from(args)?;
let mode = get_mode(matches.get_one::<String>("mode")).map_err(|e| USimpleError::new(1, e))?; let file_type = matches.get_one::<FileType>("type").unwrap();
let mode = get_mode(matches.get_one::<String>("mode")).map_err(|e| USimpleError::new(1, e))?
| file_type.as_mode();
let file_name = matches let file_name = matches
.get_one::<String>("name") .get_one::<String>("name")
.expect("Missing argument 'NAME'"); .expect("Missing argument 'NAME'");
let file_type = matches.get_one::<FileType>("type").unwrap();
// Extract the SELinux related flags and options // Extract the SELinux related flags and options
let set_selinux_context = matches.get_flag(options::SELINUX); let set_selinux_context = matches.get_flag(options::SELINUX);
let context = matches.get_one::<String>(options::CONTEXT); let context = matches.get_one::<String>(options::CONTEXT);
let mut config = Config { let dev = match (
file_type,
matches.get_one::<u64>(options::MAJOR),
matches.get_one::<u64>(options::MINOR),
) {
(FileType::Fifo, None, None) => 0,
(FileType::Fifo, _, _) => {
return Err(UUsageError::new(
1,
"Fifos do not have major and minor device numbers.",
));
}
(_, Some(&major), Some(&minor)) => makedev(major, minor),
_ => {
return Err(UUsageError::new(
1,
"Special files require major and minor device numbers.",
));
}
};
let config = Config {
mode, mode,
dev: 0, dev,
set_selinux_context: set_selinux_context || context.is_some(), set_selinux_context: set_selinux_context || context.is_some(),
context, context,
}; };
if *file_type == FileType::Fifo { let exit_code = mknod(file_name, config);
if matches.contains_id(options::MAJOR) || matches.contains_id(options::MINOR) { set_exit_code(exit_code);
Err(UUsageError::new( Ok(())
1,
"Fifos do not have major and minor device numbers.",
))
} else {
config.mode = S_IFIFO | mode;
let exit_code = mknod(file_name, config);
set_exit_code(exit_code);
Ok(())
}
} else {
match (
matches.get_one::<u64>(options::MAJOR),
matches.get_one::<u64>(options::MINOR),
) {
(_, None) | (None, _) => Err(UUsageError::new(
1,
"Special files require major and minor device numbers.",
)),
(Some(&major), Some(&minor)) => {
let dev = makedev(major, minor);
config.dev = dev;
let exit_code = match file_type {
FileType::Block => {
config.mode |= S_IFBLK;
mknod(file_name, config)
}
FileType::Character => {
config.mode |= S_IFCHR;
mknod(file_name, config)
}
FileType::Fifo => {
unreachable!("file_type was validated to be only block or character")
}
};
set_exit_code(exit_code);
Ok(())
}
}
}
} }
pub fn uu_app() -> Command { pub fn uu_app() -> Command {