refactor: extract perror

Part of #12502
This commit is contained in:
Daniel Rainer
2026-03-03 17:41:36 +01:00
committed by Johannes Altmanninger
parent bf5fa4f681
commit 7992fda9fe
15 changed files with 62 additions and 49 deletions

2
Cargo.lock generated
View File

@@ -401,7 +401,9 @@ dependencies = [
name = "fish-util"
version = "0.0.0"
dependencies = [
"errno",
"fish-widestring",
"libc",
"nix",
"rand",
]

View File

@@ -7,7 +7,9 @@ repository.workspace = true
license.workspace = true
[dependencies]
errno.workspace = true
fish-widestring.workspace = true
libc.workspace = true
nix.workspace = true
rand.workspace = true

View File

@@ -1,10 +1,15 @@
//! Generic utilities library.
use errno::errno;
use fish_widestring::prelude::*;
use rand::{SeedableRng as _, rngs::SmallRng};
use std::cmp::Ordering;
use std::os::fd::{BorrowedFd, RawFd};
use std::time;
use std::{
cmp::Ordering,
ffi::CStr,
io::Write as _,
os::fd::{BorrowedFd, RawFd},
time,
};
/// Compares two wide character strings with an (arguably) intuitive ordering. This function tries
/// to order strings in a way which is intuitive to humans with regards to sorting strings
@@ -239,6 +244,22 @@ pub fn write_to_fd(input: &[u8], fd: RawFd) -> nix::Result<usize> {
nix::unistd::write(unsafe { BorrowedFd::borrow_raw(fd) }, input)
}
/// Prints the provided string, followed by a colon, space, and the string representation of the
/// current errno via [`libc::strerror`].
pub fn perror(s: &str) {
let e = errno().0;
let mut stderr = std::io::stderr().lock();
if !s.is_empty() {
let _ = write!(stderr, "{s}: ");
}
let slice = unsafe {
let msg = libc::strerror(e);
CStr::from_ptr(msg).to_bytes()
};
let _ = stderr.write_all(slice);
let _ = stderr.write_all(b"\n");
}
#[cfg(test)]
mod tests {
use super::wcsfilecmp;

View File

@@ -6,9 +6,10 @@
fds::{BEST_O_SEARCH, wopen_dir},
parser::ParserEnvSetMode,
path::path_apply_cdpath,
wutil::{normalize_path, perror, wreadlink},
wutil::{normalize_path, wreadlink},
};
use errno::Errno;
use fish_util::perror;
use libc::{EACCES, ELOOP, ENOENT, ENOTDIR, EPERM};
use nix::unistd::fchdir;
use std::sync::Arc;

View File

@@ -4,8 +4,8 @@
use crate::parser::ParserEnvSetMode;
use crate::reader::{reader_save_screen_state, reader_write_title};
use crate::tokenizer::tok_command;
use crate::wutil::perror;
use crate::{env::EnvMode, tty_handoff::TtyHandoff};
use fish_util::perror;
use libc::STDIN_FILENO;
use nix::sys::termios::{self, tcsetattr};
use std::os::fd::BorrowedFd;

View File

@@ -25,7 +25,7 @@
use crate::tokenizer::Tok;
use crate::tokenizer::Tokenizer;
use crate::wutil;
use crate::wutil::perror;
use fish_util::perror;
use fish_wcstringutil::{split_about, split_string_tok};
use libc::SEEK_CUR;
use std::num::NonZeroUsize;

View File

@@ -1,19 +1,19 @@
use crate::common::exit_without_destructors;
use crate::fd_readable_set::{FdReadableSet, Timeout};
use crate::flog::flog;
use crate::portable_atomic::AtomicU64;
use crate::threads::assert_is_background_thread;
use crate::wutil::perror_nix;
use cfg_if::cfg_if;
use errno::errno;
use fish_util::perror;
use libc::{EAGAIN, EINTR, EWOULDBLOCK};
use std::collections::HashMap;
use std::os::unix::prelude::*;
use std::sync::atomic::Ordering;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use crate::common::exit_without_destructors;
use crate::fd_readable_set::{FdReadableSet, Timeout};
use crate::flog::flog;
use crate::threads::assert_is_background_thread;
use crate::wutil::{perror, perror_nix};
use errno::errno;
use libc::{EAGAIN, EINTR, EWOULDBLOCK};
cfg_if!(
if #[cfg(have_eventfd)] {
use libc::{EFD_CLOEXEC, EFD_NONBLOCK};

View File

@@ -1,9 +1,9 @@
use crate::flog::flog;
use crate::prelude::*;
use crate::signal::signal_check_cancel;
use crate::wutil::perror;
use crate::wutil::perror_nix;
use cfg_if::cfg_if;
use fish_util::perror;
use fish_wcstringutil::wcs2zstring;
use libc::{EINTR, F_GETFD, F_GETFL, F_SETFD, F_SETFL, FD_CLOEXEC, O_NONBLOCK, c_int};
use nix::fcntl::FcntlArg;

View File

@@ -10,8 +10,9 @@
use crate::prelude::*;
use crate::proc::JobGroupRef;
use crate::redirection::{RedirectionMode, RedirectionSpecList};
use crate::wutil::{perror, perror_io, unescape_bytes_and_write_to_fd, wdirname, wstat};
use crate::wutil::{perror_io, unescape_bytes_and_write_to_fd, wdirname, wstat};
use errno::Errno;
use fish_util::perror;
use fish_wcstringutil::wcs2bytes;
use libc::{EAGAIN, EINTR, ENOENT, ENOTDIR, EWOULDBLOCK, STDOUT_FILENO};
use nix::fcntl::OFlag;

View File

@@ -1,9 +1,8 @@
//! Safe wrappers around various libc functions that we might want to reuse across modules.
use std::time::Duration;
use crate::wutil::perror;
use fish_util::perror;
use libc::mode_t;
use std::time::Duration;
#[allow(clippy::unnecessary_cast)]
pub const fn timeval_to_duration(val: &libc::timeval) -> Duration {

View File

@@ -113,14 +113,14 @@
TtyHandoff, get_tty_protocols_active, initialize_tty_protocols, safe_deactivate_tty_protocols,
};
use crate::wildcard::wildcard_has;
use crate::wutil::{fstat, perror, perror_nix, wstat};
use crate::wutil::{fstat, perror_nix, wstat};
use crate::{abbrs, event, function};
use assert_matches::assert_matches;
use errno::{Errno, errno};
use fish_common::{UTF8_BOM_WCHAR, help_section};
use fish_fallback::fish_wcwidth;
use fish_fallback::lowercase;
use fish_util::write_to_fd;
use fish_util::{perror, write_to_fd};
use fish_wcstringutil::{
CaseSensitivity, IsPrefix, StringFuzzyMatch, count_preceding_backslashes, is_prefix,
join_strings, string_prefixes_string, string_prefixes_string_case_insensitive,

View File

@@ -1,6 +1,3 @@
use std::mem::MaybeUninit;
use std::num::NonZeroI32;
use crate::common::exit_without_destructors;
use crate::event::{enqueue_signal, is_signal_observed};
use crate::nix::getpid;
@@ -9,12 +6,17 @@
use crate::termsize::safe_termsize_invalidate_tty;
use crate::topic_monitor::{Generation, GenerationsList, Topic, topic_monitor_principal};
use crate::tty_handoff::{safe_deactivate_tty_protocols, safe_mark_tty_invalid};
use crate::wutil::{fish_wcstoi, perror};
use crate::wutil::fish_wcstoi;
use errno::{errno, set_errno};
use fish_util::perror;
use nix::sys::signal::{SaFlags, SigAction, SigHandler, SigSet, SigmaskHow, sigprocmask};
use std::sync::{
LazyLock,
atomic::{AtomicI32, Ordering},
use std::{
mem::MaybeUninit,
num::NonZeroI32,
sync::{
LazyLock,
atomic::{AtomicI32, Ordering},
},
};
/// Store the "main" pid. This allows us to reliably determine if we are in a forked child.

View File

@@ -23,7 +23,7 @@
use crate::fd_readable_set::{FdReadableSet, Timeout};
use crate::fds::{self, AutoClosePipes, make_fd_nonblocking};
use crate::flog::{FloggableDebug, flog};
use crate::wutil::perror;
use fish_util::perror;
use fish_widestring::WString;
use nix::errno::Errno;
use nix::unistd;

View File

@@ -17,7 +17,8 @@
KittyKeyboardProgressiveEnhancementsEnable, ModifyOtherKeysDisable, ModifyOtherKeysEnable,
};
use crate::threads::assert_is_main_thread;
use crate::wutil::{perror, perror_nix, wcstoi};
use crate::wutil::{perror_nix, wcstoi};
use fish_util::perror;
use libc::{EINVAL, ENOTTY, EPERM, STDIN_FILENO, WNOHANG};
use nix::sys::termios::tcgetattr;
use nix::unistd::getpgrp;

View File

@@ -12,14 +12,13 @@
use crate::flog;
use crate::signal::SigChecker;
use crate::topic_monitor::Topic;
use errno::errno;
use fish_util::write_to_fd;
use fish_util::{perror, write_to_fd};
use fish_wcstringutil::{join_strings, str2bytes_callback, wcs2osstring, wcs2zstring};
use fish_widestring::{IntoCharIter, L, WExt as _, WString, wstr};
use nix::unistd::AccessFlags;
use std::ffi::{CStr, OsStr};
use std::ffi::OsStr;
use std::fs::{self, canonicalize};
use std::io::{self, Write as _};
use std::io;
use std::os::unix::prelude::*;
pub use crate::wutil::printf::{eprintf, fprintf, printf, sprintf};
@@ -66,21 +65,6 @@ pub fn wunlink(file_name: &wstr) -> io::Result<()> {
fs::remove_file(tmp)
}
/// Port of the wide-string wperror from `src/wutil.cpp` but for rust `&str`.
pub fn perror(s: &str) {
let e = errno().0;
let mut stderr = std::io::stderr().lock();
if !s.is_empty() {
let _ = write!(stderr, "{s}: ");
}
let slice = unsafe {
let msg = libc::strerror(e);
CStr::from_ptr(msg).to_bytes()
};
let _ = stderr.write_all(slice);
let _ = stderr.write_all(b"\n");
}
pub fn perror_nix(s: &str, e: nix::errno::Errno) {
eprintf!("%s: %s\n", s, e.desc());
}