linux: ensure the netlink socket is correctly opened with older Linux kernels

It is possible for the extra socket flags (available from 2.6.27 on) to be
defined but not available. Check for this case and set the flags correctly
on the netlink socket.
This commit is contained in:
Nathan Hjelm
2013-08-07 21:01:43 -06:00
parent c848e5b72a
commit b50a433c16
2 changed files with 31 additions and 7 deletions
+30 -6
View File
@@ -63,6 +63,26 @@ static void *linux_netlink_event_thread_main(void *arg);
struct sockaddr_nl snl = { .nl_family=AF_NETLINK, .nl_groups=KERNEL };
static int set_fd_cloexec_nb (int fd)
{
int flags;
#if defined(FD_CLOEXEC)
fcntl (linux_netlink_socket, F_GETFD, &flags);
if (!(flags & FD_CLOEXEC)) {
fcntl (linux_netlink_socket, F_SETFD, flags | FD_CLOEXEC);
}
#endif
fcntl (linux_netlink_socket, F_GETFL, &flags);
if (!(flags & O_NONBLOCK)) {
fcntl (linux_netlink_socket, F_SETFL, flags | O_NONBLOCK);
}
return 0;
}
int linux_netlink_start_event_monitor(void)
{
int socktype = SOCK_RAW;
@@ -78,16 +98,20 @@ int linux_netlink_start_event_monitor(void)
#endif
linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT);
if (-1 == linux_netlink_socket && EINVAL == errno) {
linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
}
if (-1 == linux_netlink_socket) {
return LIBUSB_ERROR_OTHER;
}
#if !defined(SOCK_CLOEXEC) && defined(FD_CLOEXEC)
fcntl (linux_netlink_socket, F_SETFD, FD_CLOEXEC);
#endif
#if !defined(SOCK_NONBLOCK)
fcntl (linux_netlink_socket, F_SETFL, O_NONBLOCK);
#endif
ret = set_fd_cloexec_nb (linux_netlink_socket);
if (0 != ret) {
close (linux_netlink_socket);
linux_netlink_socket = -1;
return LIBUSB_ERROR_OTHER;
}
ret = bind(linux_netlink_socket, (struct sockaddr *) &snl, sizeof(snl));
if (0 != ret) {
+1 -1
View File
@@ -1 +1 @@
#define LIBUSB_NANO 10803
#define LIBUSB_NANO 10805