Mute alsa error on arch

This commit is contained in:
Ultradesu
2026-06-10 17:58:55 +01:00
parent 5be633d168
commit 286d42e068
5 changed files with 123 additions and 14 deletions
+41
View File
@@ -19,6 +19,7 @@ fn main() -> Result<()> {
if let Err(err) = config::logging::init() {
startup_warning = Some(format!("logging disabled: {err:#}"));
}
capture_stderr();
let (keymap, keymap_warning) = config::keymap::Keymap::load();
let startup_warning = keymap_warning.or(startup_warning);
@@ -84,6 +85,46 @@ fn run_app(
result
}
/// C libraries (ALSA on some distros, in particular) print warnings straight
/// to stderr, which corrupts the TUI. Replace stderr with a pipe and forward
/// every line into tracing — it lands in the Logs tab and the log file
/// instead of the screen.
#[cfg(unix)]
fn capture_stderr() {
use std::io::BufRead as _;
use std::os::fd::FromRawFd as _;
let mut fds = [0i32; 2];
// SAFETY: plain pipe/dup2 syscalls on freshly created fds.
unsafe {
if libc::pipe(fds.as_mut_ptr()) != 0 {
return;
}
let [read_fd, write_fd] = fds;
if libc::dup2(write_fd, libc::STDERR_FILENO) == -1 {
libc::close(read_fd);
libc::close(write_fd);
return;
}
libc::close(write_fd);
let reader = std::fs::File::from_raw_fd(read_fd);
std::thread::Builder::new()
.name("stderr".to_string())
.spawn(move || {
for line in std::io::BufReader::new(reader).lines() {
let Ok(line) = line else { break };
if !line.trim().is_empty() {
tracing::warn!(target: "stderr", "{line}");
}
}
})
.ok();
}
}
#[cfg(not(unix))]
fn capture_stderr() {}
/// Kitty keyboard protocol, where supported, disambiguates Esc from alt-keys
/// and modifier combos. The flags are popped on exit and on panic — leaving
/// them pushed corrupts the user's shell.