]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
event: replace `evutil_make_socket_nonblocking()` by an idempotent version
authorVincent Bernat <bernat@luffy.cx>
Mon, 15 Jul 2013 18:56:00 +0000 (20:56 +0200)
committerVincent Bernat <bernat@luffy.cx>
Mon, 15 Jul 2013 18:56:00 +0000 (20:56 +0200)
Once a file descriptor is locked with `BIOCLOCK`, it is not possible
to make it non-blocking. Therefore, we need to make it non-blocking
before locking it. Unfortunately, `evutil_make_socket_nonblocking()`
does not check the current value of the flag to see if there is
anything to do and we get a spurious warning. Just provide our version
of this function for this purpose.

src/daemon/event.c
src/daemon/lldpd.h
src/daemon/priv-bsd.c

index 17213c86fd858b90c5afc6ca36c68dce388be376..e1d5510be105ea2aa5fe477b3f7e2f10f1a639f4 100644 (file)
@@ -21,6 +21,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <time.h>
+#include <fcntl.h>
 #include <event2/event.h>
 #include <event2/bufferevent.h>
 #include <event2/buffer.h>
@@ -104,7 +105,7 @@ levent_snmp_add_fd(struct lldpd *cfg, int fd)
                log_warn("event", "unable to allocate memory for new SNMP event");
                return;
        }
-       evutil_make_socket_nonblocking(fd);
+       levent_make_socket_nonblocking(fd);
        if ((snmpfd->ev = event_new(base, fd,
                                    EV_READ | EV_PERSIST,
                                    levent_snmp_read,
@@ -358,7 +359,7 @@ levent_ctl_accept(evutil_socket_t fd, short what, void *arg)
                goto accept_failed;
        }
        client->cfg = cfg;
-       evutil_make_socket_nonblocking(s);
+       levent_make_socket_nonblocking(s);
        TAILQ_INSERT_TAIL(&lldpd_clients, client, next);
        if ((client->bev = bufferevent_socket_new(cfg->g_base, s,
                    BEV_OPT_CLOSE_ON_FREE)) == NULL) {
@@ -458,7 +459,7 @@ levent_init(struct lldpd *cfg)
        /* Setup unix socket */
        log_debug("event", "register Unix socket");
        TAILQ_INIT(&lldpd_clients);
-       evutil_make_socket_nonblocking(cfg->g_ctl);
+       levent_make_socket_nonblocking(cfg->g_ctl);
        if ((cfg->g_ctl_event = event_new(cfg->g_base, cfg->g_ctl,
                    EV_READ|EV_PERSIST, levent_ctl_accept, cfg)) == NULL)
                fatalx("unable to setup control socket event");
@@ -547,7 +548,7 @@ levent_hardware_add_fd(struct lldpd_hardware *hardware, int fd)
                    hardware->h_ifname);
                return;
        }
-       evutil_make_socket_nonblocking(fd);
+       levent_make_socket_nonblocking(fd);
        if ((hfd->ev = event_new(hardware->h_cfg->g_base, fd,
                    EV_READ | EV_PERSIST,
                    levent_hardware_recv,
@@ -647,7 +648,7 @@ levent_iface_subscribe(struct lldpd *cfg, int socket)
 {
        log_debug("event", "subscribe to interface changes from socket %d",
            socket);
-       evutil_make_socket_nonblocking(socket);
+       levent_make_socket_nonblocking(socket);
        cfg->g_iface_event = event_new(cfg->g_base, socket,
            EV_READ | EV_PERSIST, levent_iface_recv, cfg);
        if (cfg->g_iface_event == NULL) {
@@ -763,3 +764,19 @@ levent_schedule_pdu(struct lldpd_hardware *hardware)
                return;
        }
 }
+
+int
+levent_make_socket_nonblocking(int fd)
+{
+       int flags;
+       if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
+               log_warn("event", "fcntl(%d, F_GETFL)", fd);
+               return -1;
+       }
+       if (flags & O_NONBLOCK) return 0;
+       if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+               log_warn("event", "fcntl(%d, F_SETFL)", fd);
+               return -1;
+       }
+       return 0;
+}
index dc16e83c259ac09113f9429757fa55b081ed4ea2..58d86768ca24becf0edd026d0c4721b5a048a6d8 100644 (file)
@@ -150,6 +150,7 @@ void         levent_update_now(struct lldpd *);
 int     levent_iface_subscribe(struct lldpd *, int);
 void    levent_schedule_pdu(struct lldpd_hardware *);
 void    levent_schedule_cleanup(struct lldpd *);
+int     levent_make_socket_nonblocking(int);
 
 /* lldp.c */
 int     lldp_send(PROTO_SEND_SIG);
index 2a08875c067f9e55d3e80e8a44407ae2f2b72f3f..3a61b2d14199fb334eb78d4914c24b4d49b71e58 100644 (file)
@@ -125,7 +125,9 @@ asroot_iface_init_os(int ifindex, char *name, int *fd)
 #endif
 
 #ifdef BIOCLOCK
-       /* Lock interface */
+       /* Lock interface, but first make it non blocking since we cannot do
+        * this later */
+       levent_make_socket_nonblocking(*fd);
        if (ioctl(*fd, BIOCLOCK, (caddr_t)&enable) < 0) {
                rc = errno;
                log_info("privsep", "unable to lock BPF interface %s",