Handle a disconnecting tincd better.
authorGuus Sliepen <guus@tinc-vpn.org>
Sun, 9 Mar 2014 14:32:10 +0000 (15:32 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Sun, 9 Mar 2014 14:32:10 +0000 (15:32 +0100)
- Try to prevent SIGPIPE from being sent for errors sending to the control
  socket. We don't outright block the SIGPIPE signal because we still want the
  tinc CLI to exit when its output is actually sent to a real (broken) pipe.

- Don't call exit() from top(), and properly detect when the control socket is
  closed by the tincd.

src/tincctl.c
src/top.c

index fdb72e05469e4634b5ee411ce99e5b71e24a0520..81e7a7a2cbdbcbd4f94835769379b22a37556413 100644 (file)
 #include "tincctl.h"
 #include "top.h"
 
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
 static char **orig_argv;
 static int orig_argc;
 
@@ -529,7 +533,7 @@ bool sendline(int fd, char *format, ...) {
        blen++;
 
        while(blen) {
-               int result = send(fd, p, blen, 0);
+               int result = send(fd, p, blen, MSG_NOSIGNAL);
                if(result == -1 && errno == EINTR)
                        continue;
                else if(result <= 0)
@@ -741,6 +745,11 @@ bool connect_tincd(bool verbose) {
        freeaddrinfo(res);
 #endif
 
+#ifdef SO_NOSIGPIPE
+       static const int one = 1;
+       setsockopt(c, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof one);
+#endif
+
        char data[4096];
        int version;
 
index 4db930439ab80c205998c2f3739ab45538b303d2..2824261c2a2a94e5de48d3ce67ef8a623d9b93ac 100644 (file)
--- a/src/top.c
+++ b/src/top.c
@@ -66,8 +66,10 @@ static float bscale = 1;
 static const char *punit = "pkts";
 static float pscale = 1;
 
-static void update(int fd) {
-       sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC);
+static bool update(int fd) {
+       if(!sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC))
+               return false;
+
        gettimeofday(&cur, NULL);
 
        timersub(&cur, &prev, &diff);
@@ -90,13 +92,10 @@ static void update(int fd) {
                int n = sscanf(line, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes);
 
                if(n == 2)
-                       break;
+                       return true;
 
-               if(n != 7) {
-                       endwin();
-                       fprintf(stderr, "Error receiving traffic information\n");
-                       exit(1);
-               }
+               if(n != 7)
+                       return false;
 
                nodestats_t *found = NULL;
 
@@ -133,6 +132,8 @@ static void update(int fd) {
                found->out_packets = out_packets;
                found->out_bytes = out_bytes;
        }
+
+       return false;
 }
 
 static int cmpfloat(float a, float b) {
@@ -246,7 +247,9 @@ void top(int fd) {
        bool running = true;
 
        while(running) {
-               update(fd);
+               if(!update(fd))
+                       break;
+
                redraw();
 
                switch(getch()) {