diff --git a/src/uu/mkfifo/src/mkfifo.rs b/src/uu/mkfifo/src/mkfifo.rs index b10bd5a3b..33d842d92 100644 --- a/src/uu/mkfifo/src/mkfifo.rs +++ b/src/uu/mkfifo/src/mkfifo.rs @@ -25,20 +25,8 @@ mod options { pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; - let mode = match matches.get_one::(options::MODE) { - // if mode is passed, ignore umask - Some(m) => match usize::from_str_radix(m, 8) { - Ok(m) => m, - Err(e) => { - return Err(USimpleError::new( - 1, - translate!("mkfifo-error-invalid-mode", "error" => e), - )); - } - }, - // Default value + umask if present - None => 0o666 & !(uucore::mode::get_umask() as usize), - }; + let mode = calculate_mode(matches.get_one::(options::MODE)) + .map_err(|e| USimpleError::new(1, translate!("mkfifo-error-invalid-mode", "error" => e)))?; let fifos: Vec = match matches.get_many::(options::FIFO) { Some(v) => v.cloned().collect(), @@ -63,7 +51,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } // Explicitly set the permissions to ignore umask - if let Err(e) = fs::set_permissions(&f, fs::Permissions::from_mode(mode as u32)) { + if let Err(e) = fs::set_permissions(&f, fs::Permissions::from_mode(mode)) { return Err(USimpleError::new( 1, translate!("mkfifo-error-cannot-set-permissions", "path" => f.quote(), "error" => e), @@ -127,3 +115,22 @@ pub fn uu_app() -> Command { .value_hint(clap::ValueHint::AnyPath), ) } + +fn calculate_mode(mode_option: Option<&String>) -> Result { + let umask = uucore::mode::get_umask(); + let mut mode = 0o666; // Default mode for FIFOs + + if let Some(m) = mode_option { + if m.chars().any(|c| c.is_ascii_digit()) { + mode = uucore::mode::parse_numeric(mode, m, false)?; + } else { + for item in m.split(',') { + mode = uucore::mode::parse_symbolic(mode, item, umask, false)?; + } + } + } else { + mode &= !umask; // Apply umask if no mode is specified + } + + Ok(mode) +} diff --git a/tests/by-util/test_mkfifo.rs b/tests/by-util/test_mkfifo.rs index 7ed97b3dd..707adf71c 100644 --- a/tests/by-util/test_mkfifo.rs +++ b/tests/by-util/test_mkfifo.rs @@ -34,6 +34,13 @@ fn test_create_one_fifo_with_invalid_mode() { .arg("invalid") .fails() .stderr_contains("invalid mode"); + + new_ucmd!() + .arg("abcd") + .arg("-m") + .arg("0999") + .fails() + .stderr_contains("invalid mode"); } #[test] @@ -82,6 +89,16 @@ fn test_create_fifo_with_mode_and_umask() { test_fifo_creation("734", 0o077, "prwx-wxr--"); // spell-checker:disable-line test_fifo_creation("706", 0o777, "prwx---rw-"); // spell-checker:disable-line + test_fifo_creation("a=rwx", 0o022, "prwxrwxrwx"); // spell-checker:disable-line + test_fifo_creation("a=rx", 0o022, "pr-xr-xr-x"); // spell-checker:disable-line + test_fifo_creation("a=r", 0o022, "pr--r--r--"); // spell-checker:disable-line + test_fifo_creation("=rwx", 0o022, "prwxr-xr-x"); // spell-checker:disable-line + test_fifo_creation("u+w", 0o022, "prw-rw-rw-"); // spell-checker:disable-line + test_fifo_creation("u-w", 0o022, "pr--rw-rw-"); // spell-checker:disable-line + test_fifo_creation("u+x", 0o022, "prwxrw-rw-"); // spell-checker:disable-line + test_fifo_creation("u-r,g-w,o+x", 0o022, "p-w-r--rwx"); // spell-checker:disable-line + test_fifo_creation("a=rwx,o-w", 0o022, "prwxrwxr-x"); // spell-checker:disable-line + test_fifo_creation("=rwx,o-w", 0o022, "prwxr-xr-x"); // spell-checker:disable-line } #[test]