-gboolean avahi_netlink_work(AvahiNetlink *nl, gboolean block) {
- g_assert(nl);
-
- for (;;) {
- ssize_t bytes;
- struct nlmsghdr *p;
- guint8 buffer[64*1024];
-
- p = (struct nlmsghdr *) buffer;
+int avahi_netlink_work(AvahiNetlink *nl, int block) {
+ ssize_t bytes;
+ struct msghdr smsg;
+ struct cmsghdr *cmsg;
+ struct ucred *cred;
+ struct iovec iov;
+ struct nlmsghdr *p;
+ char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+
+ assert(nl);
+
+ iov.iov_base = nl->buffer;
+ iov.iov_len = nl->buffer_length;
+
+ smsg.msg_name = NULL;
+ smsg.msg_namelen = 0;
+ smsg.msg_iov = &iov;
+ smsg.msg_iovlen = 1;
+ smsg.msg_control = cred_msg;
+ smsg.msg_controllen = sizeof(cred_msg);
+ smsg.msg_flags = (block ? 0 : MSG_DONTWAIT);
+
+ if ((bytes = recvmsg(nl->fd, &smsg, 0)) < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ return 0;
+
+ avahi_log_error(__FILE__": recvmsg() failed: %s", strerror(errno));
+ return -1;
+ }