Improve pipe handling on linux (#3069)

This commit is contained in:
Firstyear 2024-09-29 09:36:20 +10:00 committed by GitHub
parent 983135e353
commit bdeb1a6234
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 4 deletions

View file

@ -53,7 +53,7 @@ shellexpand = { workspace = true }
time = { workspace = true, features = ["serde", "std"] } time = { workspace = true, features = ["serde", "std"] }
tracing = { workspace = true } tracing = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] } tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
tokio = { workspace = true, features = ["rt", "macros", "fs"] } tokio = { workspace = true, features = ["rt", "macros", "fs", "signal"] }
url = { workspace = true, features = ["serde"] } url = { workspace = true, features = ["serde"] }
uuid = { workspace = true } uuid = { workspace = true }
zxcvbn = { workspace = true } zxcvbn = { workspace = true }

View file

@ -13,13 +13,48 @@
use clap::Parser; use clap::Parser;
use kanidm_cli::KanidmClientParser; use kanidm_cli::KanidmClientParser;
use std::process::ExitCode;
use std::thread; use std::thread;
use tokio::runtime; use tokio::runtime;
use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::filter::LevelFilter;
use tracing_subscriber::prelude::*; use tracing_subscriber::prelude::*;
use tracing_subscriber::{fmt, EnvFilter}; use tracing_subscriber::{fmt, EnvFilter};
fn main() { #[cfg(target_family = "unix")]
use tokio::signal::unix::{signal, SignalKind};
#[cfg(target_family = "unix")]
async fn signal_handler(opt: KanidmClientParser) -> ExitCode {
// We need a signal handler to deal with a few things that can occur during runtime, especially
// sigpipe on linux.
let mut signal_quit = signal(SignalKind::quit()).expect("Invalid Signal");
let mut signal_term = signal(SignalKind::terminate()).expect("Invalid Signal");
let mut signal_pipe = signal(SignalKind::pipe()).expect("Invalid Signal");
tokio::select! {
_ = opt.commands.exec() => {
ExitCode::SUCCESS
}
_ = signal_quit.recv() => {
ExitCode::SUCCESS
}
_ = signal_term.recv() => {
ExitCode::SUCCESS
}
_ = signal_pipe.recv() => {
ExitCode::SUCCESS
}
}
}
#[cfg(target_family = "windows")]
async fn signal_handler(opt: KanidmClientParser) -> ExitCode {
opt.commands.exec().await;
ExitCode::SUCCESS
}
fn main() -> ExitCode {
let opt = KanidmClientParser::parse(); let opt = KanidmClientParser::parse();
let fmt_layer = fmt::layer().with_writer(std::io::stderr); let fmt_layer = fmt::layer().with_writer(std::io::stderr);
@ -30,7 +65,7 @@ fn main() {
Ok(f) => f, Ok(f) => f,
Err(e) => { Err(e) => {
eprintln!("ERROR! Unable to start tracing {:?}", e); eprintln!("ERROR! Unable to start tracing {:?}", e);
return; return ExitCode::FAILURE;
} }
} }
} else { } else {
@ -61,5 +96,5 @@ fn main() {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
tracing::debug!("Using {} worker threads", par_count); tracing::debug!("Using {} worker threads", par_count);
rt.block_on(async { opt.commands.exec().await }); rt.block_on(signal_handler(opt))
} }