GSource *source;
void (*callback) (flxNetlink *nl, struct nlmsghdr *n, gpointer userdata);
gpointer userdata;
- GSourceFuncs source_funcs;
};
-static gboolean work(flxNetlink *nl) {
+gboolean flx_netlink_work(flxNetlink *nl, gboolean block) {
g_assert(nl);
for (;;) {
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;
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;
}
nl->callback(nl, p, nl->userdata);
}
}
+
+ if (block)
+ break;
}
return TRUE;
nl = *((flxNetlink**) (((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) {
nl = *((flxNetlink**) (((guint8*) source) + sizeof(GSource)));
g_assert(nl);
- return work(nl);
+ return flx_netlink_work(nl, FALSE);
}
-flxNetlink *flx_netlink_new(GMainContext *context, guint32 groups, void (*cb) (flxNetlink *nl, struct nlmsghdr *n, gpointer userdata), gpointer userdata) {
+flxNetlink *flx_netlink_new(GMainContext *context, gint priority, guint32 groups, void (*cb) (flxNetlink *nl, struct nlmsghdr *n, gpointer userdata), gpointer userdata) {
int fd;
struct sockaddr_nl addr;
flxNetlink *nl;
+ static GSourceFuncs source_funcs = {
+ prepare_func,
+ check_func,
+ dispatch_func,
+ NULL,
+ NULL,
+ NULL
+ };
+
g_assert(context);
g_assert(cb);
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*));
+ nl->source = g_source_new(&source_funcs, sizeof(GSource) + sizeof(flxNetlink*));
*((flxNetlink**) (((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;