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 <PROFILE> 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>
This commit is contained in:
simonsan 2024-11-30 22:09:00 +01:00 committed by GitHub
parent c571279cba
commit 852635e25c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 1 deletions

11
Cargo.lock generated
View File

@ -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",

View File

@ -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"

View File

@ -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)
}