@@ -51,6 +51,10 @@ mod post_scans_id;
5151mod tls;
5252use post_scans:: PostScansHandler ;
5353use post_scans_id:: { PostScansId , PostScansIdHandler } ;
54+
55+ use futures:: stream:: StreamExt ;
56+ use signal_hook:: { consts:: signal:: * , low_level:: exit} ;
57+ use signal_hook_tokio:: Signals ;
5458use tokio:: net:: TcpListener ;
5559
5660pub trait ExternalError : core:: error:: Error + Send + Sync + ' static { }
@@ -374,8 +378,32 @@ impl RuntimeBuilder<runtime_builder_states::DeleteScanIDSet> {
374378 }
375379}
376380
381+ async fn handle_signals ( mut signals : Signals ) {
382+ while let Some ( signal) = signals. next ( ) . await {
383+ match signal {
384+ SIGHUP => {
385+ tracing:: info!( "Ignoring SIGHUP signal." ) ;
386+ }
387+ SIGTERM | SIGINT | SIGQUIT => {
388+ // I thought about handling it gracefully however as the request is handled in a
389+ // background task within the main loop it would just artificially complicate it
390+ // without any kind of benefit.
391+ //
392+ // The risk of corruption is relatively low, hence just exit.
393+ tracing:: info!( signal, "Exit based on signal." ) ;
394+ exit ( 128 + signal) ;
395+ }
396+ _ => unreachable ! ( ) ,
397+ }
398+ }
399+ }
400+
377401impl RuntimeBuilder < runtime_builder_states:: End > {
378402 pub async fn run_blocking ( self ) -> Result < ( ) , Box < dyn std:: error:: Error + Send + Sync > > {
403+ let signals = Signals :: new ( [ SIGHUP , SIGTERM , SIGINT , SIGQUIT ] ) ?;
404+ let _handle_guard = signals. handle ( ) ;
405+ tokio:: task:: spawn ( handle_signals ( signals) ) ;
406+
379407 let scanner = Arc :: new ( self . build_scanner ( ) ) ;
380408 let tls_config = match & self . tls {
381409 Some ( x) => Some ( tls:: tls_config ( x) ?) ,
0 commit comments