yazi/yazi-fm/src/signals.rs
2026-05-22 17:00:06 +08:00

64 lines
1.5 KiB
Rust

use anyhow::Result;
use tokio_stream::StreamExt;
pub(super) struct Signals;
impl Signals {
pub(super) fn start() -> Result<()> {
#[cfg(unix)]
use libc::{SIGCONT, SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGTSTP};
#[cfg(unix)]
let mut stream = signal_hook_tokio::Signals::new([
// Interrupt signals (Ctrl-C, Ctrl-\)
SIGINT, SIGQUIT, //
// Hangup signal (Terminal closed)
SIGHUP, //
// Termination signal (kill)
SIGTERM, //
// Job control signals (Ctrl-Z, fg/bg)
SIGTSTP, SIGCONT,
])?;
#[cfg(windows)]
let mut stream = tokio_stream::empty();
tokio::spawn(async move {
while let Some(n) = stream.next().await {
if !Self::handle(n).await {
break;
}
}
});
Ok(())
}
#[cfg(unix)]
async fn handle(n: libc::c_int) -> bool {
use libc::{SIGCONT, SIGHUP, SIGINT, SIGQUIT, SIGSTOP, SIGTERM, SIGTSTP};
use tracing::error;
use yazi_term::YIELD_TO_SUBPROCESS;
match n {
SIGINT => { /* ignored */ }
SIGQUIT | SIGHUP | SIGTERM => {
yazi_proxy::AppProxy::quit(Default::default());
return false;
}
SIGTSTP => {
yazi_scheduler::AppProxy::stop().await;
if unsafe { libc::kill(0, SIGSTOP) } != 0 {
error!("Failed to stop the process:\n{}", std::io::Error::last_os_error());
yazi_proxy::AppProxy::quit(Default::default());
}
}
SIGCONT if YIELD_TO_SUBPROCESS.try_acquire().is_ok() => {
yazi_scheduler::AppProxy::resume().await;
}
_ => {}
}
true
}
#[cfg(windows)]
async fn handle(_: ()) -> bool { unreachable!() }
}