From 69f72770761d824373a4f33f55beb9e467966ef1 Mon Sep 17 00:00:00 2001 From: David van Leusen Date: Mon, 27 Jul 2020 15:39:53 +0200 Subject: [PATCH 1/2] implement finish handler through flag instead of direct call in signal handler --- src/fping.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/fping.c b/src/fping.c index 565ac01..327266a 100644 --- a/src/fping.c +++ b/src/fping.c @@ -304,6 +304,7 @@ int hints_ai_family = AF_UNSPEC; #endif volatile sig_atomic_t status_snapshot = 0; +volatile sig_atomic_t finish_requested = 0; unsigned int debugging = 0; @@ -383,7 +384,7 @@ void print_per_system_splits(void); void print_netdata(void); void print_global_stats(void); void main_loop(); -void sigstatus(); +void signal_handler(int); void finish(); const char* sprint_tm(int64_t t); void ev_enqueue(struct event_queue *queue, struct event *event); @@ -1110,8 +1111,8 @@ int main(int argc, char** argv) init_ping_buffer_ipv6(ping_data_size); #endif - signal(SIGINT, finish); - signal(SIGQUIT, sigstatus); + signal(SIGINT, signal_handler); + signal(SIGQUIT, signal_handler); setlinebuf(stdout); if (report_interval) { @@ -1375,6 +1376,11 @@ void main_loop() break; } + /* end of loop was requested by interrupt signal handler */ + if (finish_requested) { + break; + } + /* Receive replies */ /* (this is what sleeps during each loop iteration) */ dbg_printf("waiting up to %ld ms\n", wait_time/100); @@ -1405,21 +1411,30 @@ void main_loop() /************************************************************ - Function: sigstatus + Function: signal_handler ************************************************************* - Inputs: void (none) + Inputs: int signum Description: SIGQUIT signal handler - set flag and return + SIGINT signal handler - set flag and return ************************************************************/ -void sigstatus() +void signal_handler(int signum) { - status_snapshot = 1; + switch (signum) { + case SIGINT: + finish_requested = 1; + break; + + case SIGQUIT: + status_snapshot = 1; + break; + } } From 254573f241142ea72cc9322e84724be16cc85afa Mon Sep 17 00:00:00 2001 From: David van Leusen Date: Mon, 27 Jul 2020 15:48:20 +0200 Subject: [PATCH 2/2] use sigaction when possible --- configure.ac | 4 ++++ src/fping.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/configure.ac b/configure.ac index 764e958..c7df87a 100644 --- a/configure.ac +++ b/configure.ac @@ -73,6 +73,10 @@ AC_CHECK_FUNC(connect) if test $ac_cv_func_connect = no; then AC_CHECK_LIB(socket, connect) fi +AC_CHECK_FUNC(sigaction) +if test $ac_cv_func_sigaction = yes; then + AC_DEFINE([USE_SIGACTION],[1],[Define if sigaction is available.]) +fi AH_TOP([ #ifndef CONFIG_H diff --git a/src/fping.c b/src/fping.c index 327266a..1efd4f8 100644 --- a/src/fping.c +++ b/src/fping.c @@ -434,6 +434,9 @@ int main(int argc, char** argv) uid_t uid; int tos = 0; struct optparse optparse_state; +#ifdef USE_SIGACTION + struct sigaction act; +#endif /* pre-parse -h/--help, so that we also can output help information * without trying to open the socket, which might fail */ @@ -1111,8 +1114,20 @@ int main(int argc, char** argv) init_ping_buffer_ipv6(ping_data_size); #endif +#ifdef USE_SIGACTION + memset(&act, 0, sizeof(act)); + act.sa_handler = signal_handler; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGINT); + sigaddset(&act.sa_mask, SIGQUIT); + act.sa_flags = SA_RESTART; + if (sigaction(SIGQUIT, &act, NULL) || sigaction(SIGINT, &act, NULL)) { + crash_and_burn("failure to set signal handler"); + } +#else signal(SIGINT, signal_handler); signal(SIGQUIT, signal_handler); +#endif setlinebuf(stdout); if (report_interval) {