I have a simple program with two threads. One thread listens to some user input and another listens for interface changes using a NETLINK socket. The socket is setup like so:
netlink_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
struct sockaddr_nl sa;
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sa_nl_groupds = RTMGRP_LINK;
bind(netlink_fd, reinterpret_cast<struct sockaddr *>(&sa), sizeof(sa));
and I have a loop like so:
const int RECV_BUF_SIZE = getpagesize();
char recv_buffer[RECV_BUF_SIZE];
struct iovec iov = {
.iov_base = recv_buffer,
.iov_len = sizeof(recv_buffer)
}
struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
struct msghdr msg = {
.msg_name = reinterpret_cast<void *> (&nladdr),
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
}
while(dont_quit) {
int ret = recvmsg(netlink_fd, msg, 0);
if (ret < 0) {.... show error message}
else if (ret == 0) {.... unexpected close of the socket}
else {.... process the message}
}
This code works as expected except when its time to stop. The code in thread one to stop:
dont_quit = false;
close(netlink_fd);
netlink_fd = -1;
What I expected to happen is recvmsg to unblock and to return 0 as the netlink_fd is no longer valid. Instead, I see it block until another event that would normally cause it to unblock (e.g interface change) and then go through the flow of code (as if ret > 0) and then when it comes back to the loop check, it would terminate. I have the option of changing the code to non blocking but curious to know why it didn't work as I expected?