Blame SOURCES/net-snmp-5.7.2-large-fdset.patch

e0c9be
diff -urNp old/include/net-snmp/library/large_fd_set.h new/include/net-snmp/library/large_fd_set.h
e0c9be
--- old/include/net-snmp/library/large_fd_set.h	2012-10-10 00:28:58.000000000 +0200
e0c9be
+++ new/include/net-snmp/library/large_fd_set.h	2017-04-04 14:36:27.307180033 +0200
e0c9be
@@ -55,8 +55,9 @@ extern "C" {
e0c9be
  * Number of bytes needed to store a number of file descriptors as a
e0c9be
  * struct fd_set.
e0c9be
  */
e0c9be
-#define NETSNMP_FD_SET_BYTES(setsize)                           \
e0c9be
-    (sizeof(fd_set) + ((setsize) - FD_SETSIZE) * sizeof(SOCKET))
e0c9be
+#define NETSNMP_FD_SET_BYTES(setsize)                                   \
e0c9be
+    (sizeof(fd_set) + ((setsize) > FD_SETSIZE ?                         \
e0c9be
+                       ((setsize) - FD_SETSIZE) * sizeof(SOCKET) : 0))
e0c9be
 
e0c9be
 /** Remove all sockets from the set *fdset. */
e0c9be
 #define NETSNMP_LARGE_FD_ZERO(fdset) \
e0c9be
@@ -91,9 +92,10 @@ int    netsnmp_large_fd_is_set(SOCKET fd
e0c9be
  * Number of bytes needed to store a number of file descriptors as a
e0c9be
  * struct fd_set.
e0c9be
  */
e0c9be
-#define NETSNMP_FD_SET_BYTES(setsize)                                   \
e0c9be
-    (sizeof(fd_set) + NETSNMP_FD_SET_ELEM_COUNT((setsize) - FD_SETSIZE) \
e0c9be
-     * NETSNMP_FD_MASK_SIZE)
e0c9be
+#define NETSNMP_FD_SET_BYTES(setsize)                                    \
e0c9be
+    (sizeof(fd_set) + ((setsize) > FD_SETSIZE ?                          \
e0c9be
+                       NETSNMP_FD_SET_ELEM_COUNT((setsize) - FD_SETSIZE) \
e0c9be
+                       * NETSNMP_FD_MASK_SIZE : 0))
e0c9be
 
e0c9be
 /** Remove all file descriptors from the set *fdset. */
e0c9be
 #define NETSNMP_LARGE_FD_ZERO(fdset)                            \
e0c9be
diff -urNp old/snmplib/large_fd_set.c new/snmplib/large_fd_set.c
e0c9be
--- old/snmplib/large_fd_set.c	2012-10-10 00:28:58.000000000 +0200
e0c9be
+++ new/snmplib/large_fd_set.c	2017-04-04 15:03:20.580810774 +0200
e0c9be
@@ -21,6 +21,10 @@
e0c9be
 
e0c9be
 #if !defined(cygwin) && defined(HAVE_WINSOCK_H)
e0c9be
 
e0c9be
+#define LFD_SET(n, p)    FD_SET(n, p)
e0c9be
+#define LFD_CLR(n, p)    FD_CLR(n, p)
e0c9be
+#define LFD_ISSET(n, p)  FD_ISSET(n, p)
e0c9be
+
e0c9be
 void
e0c9be
 netsnmp_large_fd_setfd(SOCKET fd, netsnmp_large_fd_set * fdset)
e0c9be
 {
e0c9be
@@ -28,18 +32,18 @@ netsnmp_large_fd_setfd(SOCKET fd, netsnm
e0c9be
 
e0c9be
     netsnmp_assert(fd != INVALID_SOCKET);
e0c9be
 
e0c9be
-    if (fdset->lfs_set.fd_count == fdset->lfs_setsize)
e0c9be
+    if (fdset->lfs_setptr->fd_count == fdset->lfs_setsize)
e0c9be
         netsnmp_large_fd_set_resize(fdset, 2 * (fdset->lfs_setsize + 1));
e0c9be
 
e0c9be
-    for (i = 0; i < fdset->lfs_set.fd_count; i++) {
e0c9be
-        if (fdset->lfs_set.fd_array[i] == (SOCKET) (fd))
e0c9be
+    for (i = 0; i < fdset->lfs_setptr->fd_count; i++) {
e0c9be
+        if (fdset->lfs_setptr->fd_array[i] == fd)
e0c9be
             break;
e0c9be
     }
e0c9be
 
e0c9be
-    if (i == fdset->lfs_set.fd_count
e0c9be
-        && fdset->lfs_set.fd_count < fdset->lfs_setsize) {
e0c9be
-        fdset->lfs_set.fd_count++;
e0c9be
-        fdset->lfs_set.fd_array[i] = fd;
e0c9be
+    if (i == fdset->lfs_setptr->fd_count &&
e0c9be
+        fdset->lfs_setptr->fd_count < fdset->lfs_setsize) {
e0c9be
+        fdset->lfs_setptr->fd_count++;
e0c9be
+        fdset->lfs_setptr->fd_array[i] = fd;
e0c9be
     }
e0c9be
 }
e0c9be
 
e0c9be
@@ -50,14 +54,14 @@ netsnmp_large_fd_clr(SOCKET fd, netsnmp_
e0c9be
 
e0c9be
     netsnmp_assert(fd != INVALID_SOCKET);
e0c9be
 
e0c9be
-    for (i = 0; i < fdset->lfs_set.fd_count; i++) {
e0c9be
-        if (fdset->lfs_set.fd_array[i] == fd) {
e0c9be
-            while (i < fdset->lfs_set.fd_count - 1) {
e0c9be
-                fdset->lfs_set.fd_array[i] =
e0c9be
-                    fdset->lfs_set.fd_array[i + 1];
e0c9be
+    for (i = 0; i < fdset->lfs_setptr->fd_count; i++) {
e0c9be
+        if (fdset->lfs_setptr->fd_array[i] == fd) {
e0c9be
+            while (i < fdset->lfs_setptr->fd_count - 1) {
e0c9be
+                fdset->lfs_setptr->fd_array[i] =
e0c9be
+                    fdset->lfs_setptr->fd_array[i + 1];
e0c9be
                 i++;
e0c9be
             }
e0c9be
-            fdset->lfs_set.fd_count--;
e0c9be
+            fdset->lfs_setptr->fd_count--;
e0c9be
             break;
e0c9be
         }
e0c9be
     }
e0c9be
@@ -70,8 +74,8 @@ netsnmp_large_fd_is_set(SOCKET fd, netsn
e0c9be
 
e0c9be
     netsnmp_assert(fd != INVALID_SOCKET);
e0c9be
 
e0c9be
-    for (i = 0; i < fdset->lfs_set.fd_count; i++) {
e0c9be
-        if (fdset->lfs_set.fd_array[i] == fd)
e0c9be
+    for (i = 0; i < fdset->lfs_setptr->fd_count; i++) {
e0c9be
+        if (fdset->lfs_setptr->fd_array[i] == fd)
e0c9be
             return 1;
e0c9be
     }
e0c9be
     return 0;
e0c9be
@@ -79,6 +83,43 @@ netsnmp_large_fd_is_set(SOCKET fd, netsn
e0c9be
 
e0c9be
 #else
e0c9be
 
e0c9be
+ /*
e0c9be
+ * Recent versions of glibc trigger abort() if FD_SET(), FD_CLR() or
e0c9be
+ * FD_ISSET() is invoked with n >= FD_SETSIZE. Hence these replacement
e0c9be
+ * functions. However, since NFDBITS != 8 * sizeof(fd_set.fds_bits[0]) for at
e0c9be
+ * least HP-UX on ia64 and since that combination uses big endian, use the
e0c9be
+ * macros from <sys/select.h> on such systems.
e0c9be
+ */
e0c9be
+NETSNMP_STATIC_INLINE void LFD_SET(unsigned n, fd_set *p)
e0c9be
+{
e0c9be
+    enum { nfdbits = 8 * sizeof(p->fds_bits[0]) };
e0c9be
+
e0c9be
+    if (nfdbits == NFDBITS)
e0c9be
+        p->fds_bits[n / nfdbits] |= (1ULL << (n % nfdbits));
e0c9be
+    else
e0c9be
+        FD_SET(n, p);
e0c9be
+}
e0c9be
+
e0c9be
+NETSNMP_STATIC_INLINE void LFD_CLR(unsigned n, fd_set *p)
e0c9be
+{
e0c9be
+    enum { nfdbits = 8 * sizeof(p->fds_bits[0]) };
e0c9be
+
e0c9be
+    if (nfdbits == NFDBITS)
e0c9be
+        p->fds_bits[n / nfdbits] &= ~(1ULL << (n % nfdbits));
e0c9be
+    else
e0c9be
+        FD_CLR(n, p);
e0c9be
+}
e0c9be
+
e0c9be
+NETSNMP_STATIC_INLINE unsigned LFD_ISSET(unsigned n, const fd_set *p)
e0c9be
+{
e0c9be
+    enum { nfdbits = 8 * sizeof(p->fds_bits[0]) };
e0c9be
+
e0c9be
+    if (nfdbits == NFDBITS)
e0c9be
+        return (p->fds_bits[n / nfdbits] & (1ULL << (n % nfdbits))) != 0;
e0c9be
+    else
e0c9be
+        return FD_ISSET(n, p) != 0;
e0c9be
+}
e0c9be
+
e0c9be
 void
e0c9be
 netsnmp_large_fd_setfd(int fd, netsnmp_large_fd_set * fdset)
e0c9be
 {
e0c9be
@@ -87,7 +128,7 @@ netsnmp_large_fd_setfd(int fd, netsnmp_l
e0c9be
     while (fd >= (int)fdset->lfs_setsize)
e0c9be
         netsnmp_large_fd_set_resize(fdset, 2 * (fdset->lfs_setsize + 1));
e0c9be
 
e0c9be
-    FD_SET(fd, fdset->lfs_setptr);
e0c9be
+    LFD_SET(fd, fdset->lfs_setptr);
e0c9be
 }
e0c9be
 
e0c9be
 void
e0c9be
@@ -96,7 +137,7 @@ netsnmp_large_fd_clr(int fd, netsnmp_lar
e0c9be
     netsnmp_assert(fd >= 0);
e0c9be
 
e0c9be
     if ((unsigned)fd < fdset->lfs_setsize)
e0c9be
-        FD_CLR(fd, fdset->lfs_setptr);
e0c9be
+        LFD_CLR(fd, fdset->lfs_setptr);
e0c9be
 }
e0c9be
 
e0c9be
 int
e0c9be
@@ -104,7 +145,7 @@ netsnmp_large_fd_is_set(int fd, netsnmp_
e0c9be
 {
e0c9be
     netsnmp_assert(fd >= 0);
e0c9be
 
e0c9be
-    return (unsigned)fd < fdset->lfs_setsize && FD_ISSET(fd, fdset->lfs_setptr);
e0c9be
+    return ((unsigned)fd < fdset->lfs_setsize && LFD_ISSET(fd, fdset->lfs_setptr));
e0c9be
 }
e0c9be
 
e0c9be
 #endif
e0c9be
@@ -174,22 +215,24 @@ netsnmp_large_fd_set_resize(netsnmp_larg
e0c9be
     }
e0c9be
 
e0c9be
 #if defined(cygwin) || !defined(HAVE_WINSOCK_H)
e0c9be
-    {
e0c9be
+    /*
e0c9be
+     * Unix: when enlarging, clear the file descriptors defined in the
e0c9be
+     * resized *fdset but that were not defined in the original *fdset.
e0c9be
+     */
e0c9be
+    if ( fdset->lfs_setsize == 0 && setsize == FD_SETSIZE ) {
e0c9be
+        /* In this case we can use the OS's FD_ZERO */
e0c9be
+        FD_ZERO(fdset->lfs_setptr);
e0c9be
+    } else {
e0c9be
         int             i;
e0c9be
-
e0c9be
-        /*
e0c9be
-         * Unix: when enlarging, clear the file descriptors defined in the
e0c9be
-         * resized *fdset but that were not defined in the original *fdset.
e0c9be
-         */
e0c9be
         for (i = fdset->lfs_setsize; i < setsize; i++)
e0c9be
-            FD_CLR(i, fdset->lfs_setptr);
e0c9be
+            LFD_CLR(i, fdset->lfs_setptr);
e0c9be
     }
e0c9be
 #endif
e0c9be
 
e0c9be
     fdset->lfs_setsize = setsize;
e0c9be
 #if !defined(cygwin) && defined(HAVE_WINSOCK_H)
e0c9be
-    if (setsize < fdset->lfs_set.fd_count)
e0c9be
-        fdset->lfs_set.fd_count = setsize;
e0c9be
+    if (setsize < fdset->lfs_setptr->fd_count)
e0c9be
+        fdset->lfs_setptr->fd_count = setsize;
e0c9be
 #endif
e0c9be
 success:
e0c9be
     return 1;
e0c9be
@@ -197,7 +240,7 @@ success:
e0c9be
 out_of_mem:
e0c9be
     fdset->lfs_setsize = 0;
e0c9be
 #if !defined(cygwin) && defined(HAVE_WINSOCK_H)
e0c9be
-    fdset->lfs_set.fd_count = 0;
e0c9be
+    fdset->lfs_setptr->fd_count = 0;
e0c9be
 #endif
e0c9be
     return 0;
e0c9be
 }