X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=netlink.c;h=12897498daf6acb12fad9fdde6c125d2559d77b4;hb=7dce450bdc23ea306a61e00f914481e29ebcb176;hp=3bc7d0160baf1341e959adaee4ed441b98ac0b68;hpb=0781d5363fb6fd723a2316fc7558aef6439b2f71;p=catta diff --git a/netlink.c b/netlink.c index 3bc7d01..1289749 100644 --- a/netlink.c +++ b/netlink.c @@ -4,16 +4,17 @@ #include "netlink.h" -struct _flxNetlink { +struct _AvahiNetlink { GMainContext *context; gint fd; guint seq; GPollFD poll_fd; GSource *source; - void (*callback) (flxNetlink *nl, struct nlmsghdr *n, gpointer userdata); + void (*callback) (AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata); gpointer userdata; }; -static gboolean work(flxNetlink *nl) { + +gboolean avahi_netlink_work(AvahiNetlink *nl, gboolean block) { g_assert(nl); for (;;) { @@ -21,7 +22,7 @@ static gboolean work(flxNetlink *nl) { ssize_t bytes; struct nlmsghdr *p = (struct nlmsghdr *) replybuf; - if ((bytes = recv(nl->fd, replybuf, sizeof(replybuf), MSG_DONTWAIT)) < 0) { + if ((bytes = recv(nl->fd, replybuf, sizeof(replybuf), block ? 0 : MSG_DONTWAIT)) < 0) { if (errno == EAGAIN || errno == EINTR) break; @@ -32,7 +33,7 @@ static gboolean work(flxNetlink *nl) { if (nl->callback) { for (; bytes > 0; p = NLMSG_NEXT(p, bytes)) { - if (!NLMSG_OK(p, bytes)) { + if (!NLMSG_OK(p, (size_t) bytes)) { g_warning("NETLINK: packet truncated"); return FALSE; } @@ -40,6 +41,9 @@ static gboolean work(flxNetlink *nl) { nl->callback(nl, p, nl->userdata); } } + + if (block) + break; } return TRUE; @@ -54,29 +58,29 @@ static gboolean prepare_func(GSource *source, gint *timeout) { } static gboolean check_func(GSource *source) { - flxNetlink* nl; + AvahiNetlink* nl; g_assert(source); - nl = *((flxNetlink**) (((guint8*) source) + sizeof(GSource))); + nl = *((AvahiNetlink**) (((guint8*) source) + sizeof(GSource))); g_assert(nl); - return nl->poll_fd.revents & G_IO_IN; + return nl->poll_fd.revents & (G_IO_IN|G_IO_HUP|G_IO_ERR); } static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer user_data) { - flxNetlink* nl; + AvahiNetlink* nl; g_assert(source); - nl = *((flxNetlink**) (((guint8*) source) + sizeof(GSource))); + nl = *((AvahiNetlink**) (((guint8*) source) + sizeof(GSource))); g_assert(nl); - return work(nl); + return avahi_netlink_work(nl, FALSE); } -flxNetlink *flx_netlink_new(GMainContext *context, guint32 groups, void (*cb) (flxNetlink *nl, struct nlmsghdr *n, gpointer userdata), gpointer userdata) { +AvahiNetlink *avahi_netlink_new(GMainContext *context, gint priority, guint32 groups, void (*cb) (AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata), gpointer userdata) { int fd; struct sockaddr_nl addr; - flxNetlink *nl; + AvahiNetlink *nl; static GSourceFuncs source_funcs = { prepare_func, @@ -106,7 +110,7 @@ flxNetlink *flx_netlink_new(GMainContext *context, guint32 groups, void (*cb) (f return NULL; } - nl = g_new(flxNetlink, 1); + nl = g_new(AvahiNetlink, 1); nl->context = context; g_main_context_ref(context); nl->fd = fd; @@ -114,9 +118,11 @@ flxNetlink *flx_netlink_new(GMainContext *context, guint32 groups, void (*cb) (f nl->callback = cb; nl->userdata = userdata; - nl->source = g_source_new(&source_funcs, sizeof(GSource) + sizeof(flxNetlink*)); - *((flxNetlink**) (((guint8*) nl->source) + sizeof(GSource))) = nl; + nl->source = g_source_new(&source_funcs, sizeof(GSource) + sizeof(AvahiNetlink*)); + *((AvahiNetlink**) (((guint8*) nl->source) + sizeof(GSource))) = nl; + g_source_set_priority(nl->source, priority); + memset(&nl->poll_fd, 0, sizeof(GPollFD)); nl->poll_fd.fd = fd; nl->poll_fd.events = G_IO_IN|G_IO_ERR|G_IO_HUP; @@ -127,7 +133,7 @@ flxNetlink *flx_netlink_new(GMainContext *context, guint32 groups, void (*cb) (f return nl; } -void flx_netlink_free(flxNetlink *nl) { +void avahi_netlink_free(AvahiNetlink *nl) { g_assert(nl); g_source_destroy(nl->source); @@ -137,7 +143,7 @@ void flx_netlink_free(flxNetlink *nl) { g_free(nl); } -int flx_netlink_send(flxNetlink *nl, struct nlmsghdr *m, guint *ret_seq) { +int avahi_netlink_send(AvahiNetlink *nl, struct nlmsghdr *m, guint *ret_seq) { g_assert(nl); g_assert(m);