X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=netlink.c;h=12897498daf6acb12fad9fdde6c125d2559d77b4;hb=7dce450bdc23ea306a61e00f914481e29ebcb176;hp=a04e6c9a42d9235c8520899b5cd14974ed9b4816;hpb=33ccd714ea9469b5b7d3b36bbe468ba1b0f31dfc;p=catta diff --git a/netlink.c b/netlink.c index a04e6c9..1289749 100644 --- a/netlink.c +++ b/netlink.c @@ -4,18 +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; - GSourceFuncs source_funcs; }; -static gboolean work(flxNetlink *nl) { +gboolean avahi_netlink_work(AvahiNetlink *nl, gboolean block) { g_assert(nl); for (;;) { @@ -23,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; @@ -34,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; } @@ -42,6 +41,9 @@ static gboolean work(flxNetlink *nl) { nl->callback(nl, p, nl->userdata); } } + + if (block) + break; } return TRUE; @@ -56,30 +58,39 @@ 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, + check_func, + dispatch_func, + NULL, + NULL, + NULL + }; + g_assert(context); g_assert(cb); @@ -99,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; @@ -107,14 +118,11 @@ flxNetlink *flx_netlink_new(GMainContext *context, guint32 groups, void (*cb) (f nl->callback = cb; nl->userdata = userdata; - memset(&nl->source_funcs, 0, sizeof(nl->source_funcs)); - nl->source_funcs.prepare = prepare_func; - nl->source_funcs.check = check_func; - nl->source_funcs.dispatch = dispatch_func, - - nl->source = g_source_new(&nl->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; @@ -125,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); @@ -135,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);