0

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?

incubus
  • 681
  • 1
  • 5
  • 21
  • 1
    Since it's a C API you're calling, a C answer should be appropriate. Get you headed in the right direction at least. I like the second answer more than the first. Lower potential for surprises. – user4581301 Apr 03 '20 at 15:57
  • Agree, second answer is better - already tried the shutdown and it didn't work. – incubus Apr 03 '20 at 17:25

0 Answers0