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