]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
report: print partial output on interrupt 589/head
authorDarafei Praliaskouski <me@komzpa.net>
Thu, 7 May 2026 20:41:00 +0000 (00:41 +0400)
committerDarafei Praliaskouski <me@komzpa.net>
Fri, 8 May 2026 03:07:55 +0000 (07:07 +0400)
ui/mtr.c
ui/mtr.h
ui/select.c

index 6886bce346c52adb60868055f9331c567dcf4e14..14db803a55af66123d58386b863c5563e6f3e5b1 100644 (file)
--- a/ui/mtr.c
+++ b/ui/mtr.c
@@ -45,6 +45,7 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <locale.h>
+#include <signal.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 
@@ -868,6 +869,10 @@ int main(
         display_close(&ctl);
         unlock(stdout);
 
+        if (ctl.Interrupted) {
+            exit_val = 128 + SIGINT;
+            break;
+        }
         if (ctl.Interactive)
             break;
         else
index 8e01cd4f5c5a277fec73793a9026655f85c5c8bb..b71b43a2f370dff6685fa3778b35b3ccafb9b77d 100644 (file)
--- a/ui/mtr.h
+++ b/ui/mtr.h
@@ -113,6 +113,7 @@ struct mtr_ctl {
     int fld_index[FLD_INDEX_SZ];        /* default display field (defined by key in net.h) and order */
     char available_options[MAXFLD];
     int display_offset;         /* only used in text mode */
+    int Interrupted;
     void *gtk_data;             /* pointer to hold arbitrary gtk data */
     unsigned int                /* bit field to hold named booleans */
      ForceMaxPing:1,
index a854c22ab6d0b8f3c50432b93de5ce216b26caef..04fe4a27d6e9c210477bb8d902e2028df46d881e 100644 (file)
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <math.h>
 #include <errno.h>
+#include <signal.h>
 #ifdef HAVE_ERROR_H
 #include <error.h>
 #else
 
 #define MIN_DISPLAY_REDRAW_USEC 100000
 
+static volatile sig_atomic_t interrupted;
+
+static void interrupt_handler(
+    int signum ATTRIBUTE_UNUSED)
+{
+    interrupted = 1;
+}
+
+
 static int timeval_after_or_equal(
     const struct timeval *a,
     const struct timeval *b)
@@ -113,12 +123,20 @@ void select_loop(
     struct timeval intervaltime;
     static double dnsinterval = 0;
 
+    interrupted = 0;
+    signal(SIGINT, interrupt_handler);
+
     memset(&startgrace, 0, sizeof(startgrace));
 
     gettimeofday(&lasttime, NULL);
     nextredraw = lasttime;
 
     while (1) {
+        if (interrupted) {
+            ctl->Interrupted = 1;
+            return;
+        }
+
         dt = calc_deltatime(ctl->WaitTime);
         intervaltime.tv_sec = dt / 1000000;
         intervaltime.tv_usec = dt % 1000000;
@@ -248,7 +266,12 @@ void select_loop(
                 rv = select(maxfd, (void *) &readfd, NULL, NULL,
                             &selecttime);
             }
-        } while ((rv < 0) && (errno == EINTR));
+        } while ((rv < 0) && (errno == EINTR) && !interrupted);
+
+        if (interrupted) {
+            ctl->Interrupted = 1;
+            return;
+        }
 
         if (rv < 0) {
             error(EXIT_FAILURE, errno, "Select failed");