Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/uu/mkfifo/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,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-missing-operand = missing operand
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
2 changes: 1 addition & 1 deletion src/uu/mkfifo/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,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-missing-operand = opérande manquant
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
26 changes: 18 additions & 8 deletions src/uu/mkfifo/src/mkfifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
use clap::{Arg, ArgAction, Command, value_parser};
use rustix::fs::Mode;
use rustix::process::umask;
use std::io;
use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError};
use uucore::error::{UIoError, UResult, USimpleError};
use uucore::translate;

use uucore::{format_usage, show};
Expand Down Expand Up @@ -55,10 +56,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" => UIoError::from(e)
),
));
} else {
// Apply SELinux context if requested
Expand Down Expand Up @@ -136,19 +141,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<(), 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(|errno: rustix::io::Errno| io::Error::from_raw_os_error(errno.raw_os_error()))
}

#[cfg(target_vendor = "apple")]
fn create_fifo(path: &str, mode: u32) -> Result<(), ()> {
fn create_fifo(path: &str, mode: u32) -> Result<(), io::Error> {
use std::ffi::CString;
let c_path = CString::new(path).map_err(|_| ())?;
let c_path = CString::new(path).map_err(|e| io::Error::new(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(io::Error::last_os_error())
}
}

fn calculate_mode(mode_option: Option<&String>) -> Result<u32, String> {
Expand Down
10 changes: 10 additions & 0 deletions tests/by-util/test_mkfifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ fn test_create_one_fifo_already_exists() {
.stderr_is("mkfifo: cannot create fifo 'abcdef': File exists\n");
}

#[test]
fn test_create_fifo_in_missing_directory() {
// Regression test for #12669: when the parent directory doesn't exist,
// mkfifo used to always report "File exists" regardless of the actual
// OS error. It should report the real reason instead, matching GNU.
new_ucmd!().arg("no-such-directory/fifo").fails().stderr_is(
"mkfifo: cannot create fifo 'no-such-directory/fifo': No such file or directory\n",
);
}

#[test]
fn test_create_fifo_with_mode_and_umask() {
use uucore::fs::display_permissions;
Expand Down
Loading