From 852635e25c39b5ccd9f4c7b6bc544cc3f9a2f453 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Sat, 30 Nov 2024 22:09:00 +0100 Subject: [PATCH] feat: shut down gracefully with ctrl+c (#1364) If you have a long-running process, like `webdav` or `backup` or others, pressing CTRL+C usually results in a non-zero exit code: `process didn't exit successfully: P:\CARGO\.cargo-target-win\debug\rustic.exe -P webdav (exit code: 0xc000013a, STATUS_CONTROL_C_EXIT)` This shouldn't be the case, as it was user initiated and we can shut down gracefully. This PR adds this functionality, so CTRL+C shuts down `rustic` gracefully and exits with a 0 exit-code. --------- Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> Co-authored-by: aawsome <37850842+aawsome@users.noreply.github.com> --- Cargo.lock | 11 +++++++++++ Cargo.toml | 1 + src/commands.rs | 17 ++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8f132822f..68b997783 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -896,6 +896,16 @@ dependencies = [ "cipher", ] +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -3861,6 +3871,7 @@ dependencies = [ "conflate", "convert_case", "crossterm", + "ctrlc", "dateparser", "dav-server", "derive_more", diff --git a/Cargo.toml b/Cargo.toml index e2f1a0dfc..10f1d9d7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,6 +103,7 @@ clap = { version = "4", features = ["derive", "env", "wrap_help"] } clap_complete = "4" conflate = "0.3.3" convert_case = "0.6.0" +ctrlc = { version = "3.4.5", features = ["termination"] } dateparser = "0.2.1" derive_more = { version = "1", features = ["debug"] } dialoguer = "0.11.0" diff --git a/src/commands.rs b/src/commands.rs index 0b242ea10..5ac4af30b 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -35,6 +35,7 @@ use std::fmt::Debug; use std::fs::File; use std::path::PathBuf; use std::str::FromStr; +use std::sync::mpsc::channel; #[cfg(feature = "mount")] use crate::commands::mount::MountCmd; @@ -64,7 +65,7 @@ use clap::builder::{ }; use convert_case::{Case, Casing}; use human_panic::setup_panic; -use log::{log, Level}; +use log::{info, log, Level}; use simplelog::{CombinedLogger, LevelFilter, TermLogger, TerminalMode, WriteLogger}; use self::find::FindCmd; @@ -179,6 +180,20 @@ impl Runnable for EntryPoint { // Set up panic hook for better error messages and logs setup_panic!(); + // Set up Ctrl-C handler + let (tx, rx) = channel(); + + ctrlc::set_handler(move || tx.send(()).expect("Could not send signal on channel.")) + .expect("Error setting Ctrl-C handler"); + + _ = std::thread::spawn(move || { + // Wait for Ctrl-C + rx.recv().expect("Could not receive from channel."); + info!("Ctrl-C received, shutting down..."); + RUSTIC_APP.shutdown(Shutdown::Graceful) + }); + + // Run the subcommand self.commands.run(); RUSTIC_APP.shutdown(Shutdown::Graceful) }