Fix issue when we try and poll for fd -1 by deleting events by argument.
authorRoy Marples <roy@marples.name>
Sat, 7 Mar 2015 08:53:52 +0000 (08:53 +0000)
committerRoy Marples <roy@marples.name>
Sat, 7 Mar 2015 08:53:52 +0000 (08:53 +0000)
Clear status line correctly when a new status with less chars is set.
Clear summary window when lost connection.
Add msec timeout to reflect the real DHCPCD_RETRYOPEN length.

src/dhcpcd-curses/dhcpcd-curses.c
src/dhcpcd-curses/dhcpcd-curses.h
src/dhcpcd-curses/eloop.c
src/dhcpcd-curses/eloop.h

index 739b9bdb205e698c6b1047aa122380c7f3f80034..c957a52df855e6fcf476df9826f3e9f0e9d69478 100644 (file)
@@ -54,15 +54,23 @@ const int handle_sigs[] = {
 /* Handling signals needs *some* context */
 static struct ctx *_ctx;
 
+static void try_open(void *);
+
 static void
 set_status(struct ctx *ctx, const char *status)
 {
        int h, w;
+       size_t slen;
 
        getmaxyx(ctx->win_status, h, w);
-       w -= strlen(status);
+       w -= (slen = strlen(status));
+       if (ctx->status_len > slen) {
+               wmove(ctx->win_status, 0, w - (int)(ctx->status_len - slen));
+               wclrtoeol(ctx->win_status);
+       }
        mvwprintw(ctx->win_status, 0, w, "%s", status);
        wrefresh(ctx->win_status);
+       ctx->status_len = slen;
 }
 
 static int
@@ -71,7 +79,10 @@ set_summary(struct ctx *ctx, const char *msg)
        int r;
 
        wclear(ctx->win_summary);
-       r = wprintw(ctx->win_summary, "%s", msg);
+       if (msg)
+               r = wprintw(ctx->win_summary, "%s", msg);
+       else
+               r = 0;
        wrefresh(ctx->win_summary);
        return r;
 }
@@ -184,6 +195,14 @@ dispatch(void *arg)
 {
        struct ctx *ctx = arg;
 
+       if (dhcpcd_get_fd(ctx->con) == -1) {
+               warning(ctx, _("dhcpcd connection lost"));
+               eloop_event_delete(ctx->eloop, -1, NULL, ctx->con, 0);
+               eloop_timeout_add_msec(ctx->eloop, DHCPCD_RETRYOPEN,
+                   try_open, ctx);
+               return;
+       }
+
        dhcpcd_dispatch(ctx->con);
 }
 
@@ -204,7 +223,7 @@ try_open(void *arg)
                        last_error = errno;
                        set_status(ctx, strerror(errno));
                }
-               eloop_timeout_add_sec(ctx->eloop, DHCPCD_RETRYOPEN,
+               eloop_timeout_add_msec(ctx->eloop, DHCPCD_RETRYOPEN,
                    try_open, ctx);
                return;
        }
@@ -224,7 +243,15 @@ status_cb(DHCPCD_CONNECTION *con, const char *status, void *arg)
        debug(ctx, _("Status changed to %s"), status);
        set_status(ctx, status);
 
-       if (strcmp(status, "down") != 0) {
+       if (strcmp(status, "down") == 0) {
+               eloop_event_delete(ctx->eloop, ctx->fd, NULL, NULL, 0);
+               ctx->fd = -1;
+               ctx->online = ctx->carrier = false;
+               eloop_timeout_delete(ctx->eloop, NULL, ctx);
+               set_summary(ctx, NULL);
+               eloop_timeout_add_msec(ctx->eloop, DHCPCD_RETRYOPEN,
+                   try_open, ctx);
+       } else {
                bool refresh;
 
                if (ctx->last_status == NULL ||
@@ -241,13 +268,6 @@ status_cb(DHCPCD_CONNECTION *con, const char *status, void *arg)
 
        free(ctx->last_status);
        ctx->last_status = strdup(status);
-
-       if (strcmp(status, "down") == 0) {
-               ctx->online = ctx->carrier = false;
-               eloop_timeout_add_sec(ctx->eloop, DHCPCD_RETRYOPEN,
-                   try_open, ctx);
-               return;
-       }
 }
 
 static void
@@ -388,7 +408,7 @@ wpa_status_cb(DHCPCD_WPA *wpa, const char *status, void *arg)
        i = dhcpcd_wpa_if(wpa);
        debug(ctx, _("%s: WPA status %s"), i->ifname, status);
        if (strcmp(status, "down") == 0) {
-               eloop_event_delete(ctx->eloop, dhcpcd_wpa_get_fd(wpa), 0);
+               eloop_event_delete(ctx->eloop, -1, NULL, wpa, 0);
                TAILQ_FOREACH_SAFE(w, &ctx->wi_scans, next, wn) {
                        if (w->interface == i) {
                                TAILQ_REMOVE(&ctx->wi_scans, w, next);
@@ -415,9 +435,8 @@ bg_scan(void *arg)
                }
        }
 
-       /* DHCPCD_WPA_SCAN_SHORT is in milliseconds */
-       eloop_timeout_add_sec(ctx->eloop,
-            DHCPCD_WPA_SCAN_SHORT / 1000, bg_scan, ctx);
+       eloop_timeout_add_msec(ctx->eloop, DHCPCD_WPA_SCAN_SHORT,
+           bg_scan, ctx);
 }
 #endif
 
@@ -537,9 +556,8 @@ main(void)
 
        eloop_timeout_add_sec(ctx.eloop, 0, try_open, &ctx);
 #ifdef BG_SCAN
-       /* DHCPCD_WPA_SCAN_SHORT is in milliseconds */
-       eloop_timeout_add_sec(ctx.eloop,
-           DHCPCD_WPA_SCAN_SHORT / 1000, bg_scan, &ctx);
+       eloop_timeout_add_msec(ctx.eloop, DHCPCD_WPA_SCAN_SHORT,
+           bg_scan, &ctx);
 #endif
        eloop_start(ctx.eloop);
 
index 1f1d93121911b7b072459fd391e703194b80d645..6aca30e0aaaf47d5004f16a4c18d2f25910cb519 100644 (file)
@@ -64,6 +64,7 @@ struct ctx {
        bool online;
        bool carrier;
        char *last_status;
+       size_t status_len;
        WI_SCANS wi_scans;
 
        WINDOW *stdscr;
index b32a8cfb1a92538b4869f5428cce65298299d446..e381189f6ba17762dacd2ab3ec88277771ba6aaa 100644 (file)
@@ -34,6 +34,8 @@
 #include <stdlib.h>
 #include <syslog.h>
 
+#include <stdio.h>
+
 #define IN_ELOOP
 
 #include "config.h"
@@ -192,12 +194,15 @@ eloop_event_add(ELOOP_CTX *ctx, int fd,
 }
 
 void
-eloop_event_delete(ELOOP_CTX *ctx, int fd, int write_only)
+eloop_event_delete(ELOOP_CTX *ctx, int fd, void (*callback)(void *), void *arg,
+    int write_only)
 {
        struct eloop_event *e;
 
        TAILQ_FOREACH(e, &ctx->events, next) {
-               if (e->fd == fd) {
+               if (e->fd == fd ||
+                   e->read_cb == callback || (arg && e->read_cb_arg == arg))
+               {
                        if (write_only) {
                                e->write_cb = NULL;
                                e->write_cb_arg = NULL;
@@ -278,6 +283,26 @@ eloop_q_timeout_add_sec(ELOOP_CTX *ctx, int queue, time_t when,
        return eloop_q_timeout_add_tv(ctx, queue, &tv, callback, arg);
 }
 
+#define USEC_PER_SEC           1000000L
+#define timernorm(tv) do {                                             \
+       while ((tv)->tv_usec >=  USEC_PER_SEC) {                        \
+               (tv)->tv_sec++;                                         \
+               (tv)->tv_usec -= USEC_PER_SEC;                          \
+       }                                                               \
+} while (0 /* CONSTCOND */);
+
+int
+eloop_q_timeout_add_msec(ELOOP_CTX *ctx, int queue, suseconds_t when,
+    void (*callback)(void *), void *arg)
+{
+       struct timeval tv;
+
+       tv.tv_sec = 0;
+       tv.tv_usec = when * 1000;
+       timernorm(&tv);
+       return eloop_q_timeout_add_tv(ctx, queue, &tv, callback, arg);
+}
+
 int
 eloop_timeout_add_now(ELOOP_CTX *ctx,
     void (*callback)(void *), void *arg)
index bf40c90631124cc34598b6d72509ab6ee1ff814a..23e4d6b6d3556107df719e814a0f52aa8f829997 100644 (file)
@@ -84,15 +84,19 @@ typedef void *ELOOP_CTX;
     eloop_q_timeout_add_tv(a, ELOOP_QUEUE, b, c, d)
 #define eloop_timeout_add_sec(a, b, c, d) \
     eloop_q_timeout_add_sec(a, ELOOP_QUEUE, b, c, d)
+#define eloop_timeout_add_msec(a, b, c, d) \
+    eloop_q_timeout_add_msec(a, ELOOP_QUEUE, b, c, d)
 #define eloop_timeout_delete(a, b, c) \
     eloop_q_timeout_delete(a, ELOOP_QUEUE, b, c)
 
 int eloop_event_add(ELOOP_CTX *, int,
     void (*)(void *), void *,
     void (*)(void *), void *);
-void eloop_event_delete(ELOOP_CTX *, int, int);
+void eloop_event_delete(ELOOP_CTX *, int, void (*)(void *), void *, int);
 int eloop_q_timeout_add_sec(ELOOP_CTX *, int queue,
     time_t, void (*)(void *), void *);
+int eloop_q_timeout_add_msec(ELOOP_CTX *, int queue,
+    suseconds_t, void (*)(void *), void *);
 int eloop_q_timeout_add_tv(ELOOP_CTX *, int queue,
     const struct timeval *, void (*)(void *), void *);
 int eloop_timeout_add_now(ELOOP_CTX *, void (*)(void *), void *);