diff --git a/src/main.rs b/src/main.rs index 8eef2e8c..b4885831 100644 --- a/src/main.rs +++ b/src/main.rs @@ -558,6 +558,11 @@ async fn launch_rocket(pool: db::DbPool, extra_debug: bool) -> Result<(), Error> let basepath = &CONFIG.domain_path(); let mut config = rocket::Config::from(rocket::Config::figment()); + + // We install our own signal handlers below; disable Rocket's built-in handlers + config.shutdown.ctrlc = false; + config.shutdown.signals.clear(); + config.temp_dir = canonicalize(CONFIG.tmp_folder()).unwrap().into(); config.cli_colors = false; // Make sure Rocket does not color any values for logging. config.limits = Limits::new() @@ -589,11 +594,7 @@ async fn launch_rocket(pool: db::DbPool, extra_debug: bool) -> Result<(), Error> CONFIG.set_rocket_shutdown_handle(instance.shutdown()); - tokio::spawn(async move { - tokio::signal::ctrl_c().await.expect("Error setting Ctrl-C handler"); - info!("Exiting Vaultwarden!"); - CONFIG.shutdown(); - }); + spawn_shutdown_signal_handler(); #[cfg(all(unix, sqlite))] { @@ -621,6 +622,35 @@ async fn launch_rocket(pool: db::DbPool, extra_debug: bool) -> Result<(), Error> Ok(()) } +#[cfg(unix)] +fn spawn_shutdown_signal_handler() { + tokio::spawn(async move { + use tokio::signal::unix::signal; + + let mut sigint = signal(SignalKind::interrupt()).expect("Error setting SIGINT handler"); + let mut sigterm = signal(SignalKind::terminate()).expect("Error setting SIGTERM handler"); + let mut sigquit = signal(SignalKind::quit()).expect("Error setting SIGQUIT handler"); + + let signal_name = tokio::select! { + _ = sigint.recv() => "SIGINT", + _ = sigterm.recv() => "SIGTERM", + _ = sigquit.recv() => "SIGQUIT", + }; + + info!("Received {signal_name}, initiating graceful shutdown"); + CONFIG.shutdown(); + }); +} + +#[cfg(not(unix))] +fn spawn_shutdown_signal_handler() { + tokio::spawn(async move { + tokio::signal::ctrl_c().await.expect("Error setting Ctrl-C handler"); + info!("Received Ctrl-C, initiating graceful shutdown"); + CONFIG.shutdown(); + }); +} + fn schedule_jobs(pool: db::DbPool) { if CONFIG.job_poll_interval_ms() == 0 { info!("Job scheduler disabled.");