- // recvmsg?
- while let Ok(n) = recv(fd, &mut buf, MsgFlags::empty()) {
- println!("something on the netlink socket: {} bytes", n);
- let nlmsg_ptr = &buf as *const _ as *const nlmsghdr;
- let nlmsg = unsafe { &*nlmsg_ptr };
- // Right conventionally there's some trick here involving macros NLMSG_OK
- // I can presumably do this using NetlinkGeneric too
- // It's unclear whether this is worse or not - need to know what those macros do
+ let mut handle_update = move |new_list: List| {
+ if new_list == prev_list {
+ return;
+ }
+ let update = Update {
+ interfaces: new_list.0.clone(),
+ diff: new_list.diff_from(&prev_list),
+ };
+ (callback)(update);
+ prev_list = new_list;
+ };
+
+ if let Ok(initial) = crate::list::list_interfaces() {
+ handle_update(initial);
+ };
+
+ loop {
+ let mut fds = [
+ pollfd {
+ fd: sockfd.as_raw_fd(),
+ events: POLLIN,
+ revents: 0,
+ },
+ pollfd {
+ fd: pipe_rd.as_raw_fd(),
+ events: POLLIN,
+ revents: 0,
+ },
+ ];
+ unsafe {
+ poll(&mut fds as *mut _, 2, -1);
+ }
+ if fds[0].revents != 0 {
+ // netlink socket had something happen
+ if recv(sockfd.as_raw_fd(), &mut buf, MsgFlags::empty()).is_ok() {
+ let Ok(new_list) = crate::list::list_interfaces() else {
+ continue;
+ };
+ handle_update(new_list);
+ }
+ }
+ if fds[1].revents != 0 {
+ // pipe had something happen
+ break;
+ }