diff --git a/src/uu/mkfifo/locales/en-US.ftl b/src/uu/mkfifo/locales/en-US.ftl index 65d2846c3d3..f66a6b0459a 100644 --- a/src/uu/mkfifo/locales/en-US.ftl +++ b/src/uu/mkfifo/locales/en-US.ftl @@ -8,6 +8,6 @@ mkfifo-help-context = like -Z, or if CTX is specified then set the SELinux or SM # Error messages mkfifo-error-invalid-mode = invalid mode: { $error } -mkfifo-error-cannot-create-fifo = cannot create fifo { $path }: File exists +mkfifo-error-cannot-create-fifo = cannot create fifo { $path }: { $error } mkfifo-error-cannot-set-permissions = cannot set permissions on { $path }: { $error } mkfifo-error-non-file-permission = mode must specify only file permission bits diff --git a/src/uu/mkfifo/locales/fr-FR.ftl b/src/uu/mkfifo/locales/fr-FR.ftl index 8beb254ecd0..038d8284927 100644 --- a/src/uu/mkfifo/locales/fr-FR.ftl +++ b/src/uu/mkfifo/locales/fr-FR.ftl @@ -8,6 +8,6 @@ mkfifo-help-context = comme -Z, ou si CTX est spécifié, définir le contexte d # Messages d'erreur mkfifo-error-invalid-mode = mode invalide : { $error } -mkfifo-error-cannot-create-fifo = impossible de créer le fifo { $path } : Le fichier existe +mkfifo-error-cannot-create-fifo = impossible de créer le fifo { $path } : { $error } mkfifo-error-cannot-set-permissions = impossible de définir les permissions sur { $path } : { $error } mkfifo-error-non-file-permission = le mode ne doit spécifier que des bits de permission de fichier diff --git a/src/uu/mkfifo/src/mkfifo.rs b/src/uu/mkfifo/src/mkfifo.rs index 22d0b2350d3..666e75a6388 100644 --- a/src/uu/mkfifo/src/mkfifo.rs +++ b/src/uu/mkfifo/src/mkfifo.rs @@ -7,7 +7,7 @@ use clap::{Arg, ArgAction, Command, value_parser}; use rustix::fs::Mode; use rustix::process::umask; use uucore::display::Quotable; -use uucore::error::{UResult, USimpleError}; +use uucore::error::{UResult, USimpleError, strip_errno}; use uucore::translate; use uucore::{format_usage, show}; @@ -52,10 +52,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let mkfifo_result = create_fifo(f.as_str(), mode); umask(prev_umask); - if mkfifo_result.is_err() { + if let Err(e) = mkfifo_result { show!(USimpleError::new( 1, - translate!("mkfifo-error-cannot-create-fifo", "path" => f.quote()), + translate!( + "mkfifo-error-cannot-create-fifo", + "path" => f.quote(), + "error" => strip_errno(&e) + ), )); } else { // Apply SELinux context if requested @@ -134,19 +138,24 @@ pub fn uu_app() -> Command { // libc's path-based `mkfifo` there. Both rely on the caller having cleared // the umask so the requested mode is applied atomically (see issue #10020). #[cfg(not(target_vendor = "apple"))] -fn create_fifo(path: &str, mode: u32) -> Result<(), ()> { +fn create_fifo(path: &str, mode: u32) -> Result<(), std::io::Error> { use rustix::fs::{CWD, mkfifoat}; - mkfifoat(CWD, path, Mode::from_bits_truncate(mode)).map_err(|_| ()) + mkfifoat(CWD, path, Mode::from_bits_truncate(mode)).map_err(std::io::Error::from) } #[cfg(target_vendor = "apple")] -fn create_fifo(path: &str, mode: u32) -> Result<(), ()> { +fn create_fifo(path: &str, mode: u32) -> Result<(), std::io::Error> { use std::ffi::CString; - let c_path = CString::new(path).map_err(|_| ())?; + let c_path = + CString::new(path).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?; // SAFETY: `c_path` is a valid NUL-terminated C string and `mode` is a // standard mode_t bit pattern. let rc = unsafe { libc::mkfifo(c_path.as_ptr(), mode as libc::mode_t) }; - if rc == 0 { Ok(()) } else { Err(()) } + if rc == 0 { + Ok(()) + } else { + Err(std::io::Error::last_os_error()) + } } fn calculate_mode(mode_option: Option<&String>) -> Result { diff --git a/tests/by-util/test_mkfifo.rs b/tests/by-util/test_mkfifo.rs index 416132e1073..a0a0ecfbc0b 100644 --- a/tests/by-util/test_mkfifo.rs +++ b/tests/by-util/test_mkfifo.rs @@ -156,9 +156,10 @@ fn test_create_fifo_permission_denied() { at.mkdir(no_exec_dir); at.set_mode(no_exec_dir, 0o644); - // We no longer attempt to modify file permission if the file was failed to be created. - // Therefore the error message should only contain "cannot create". - let err_msg = format!("mkfifo: cannot create fifo '{named_pipe}': File exists\n"); + // The parent directory has no execute bit, so the kernel refuses to add + // an entry to it (EACCES). mkfifo should surface that reason instead of + // the old hardcoded "File exists". + let err_msg = format!("mkfifo: cannot create fifo '{named_pipe}': Permission denied\n"); scene .ucmd()