large_fd_set.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /**
  2. * @file large_fd_set.h
  3. *
  4. * @brief Macro's and functions for manipulation of large file descriptor sets.
  5. */
  6. #ifndef LARGE_FD_SET_H
  7. #define LARGE_FD_SET_H
  8. #include <net-snmp/net-snmp-config.h>
  9. #include <net-snmp/types.h>
  10. #ifdef HAVE_SYS_SELECT_H
  11. #include <sys/select.h>
  12. #endif
  13. #if defined(HAVE_WINSOCK_H) && !defined(_WINSOCKAPI_) && !defined(_WINSOCK_H)
  14. #error <winsock.h> or <winsock2.h> must have been included before this file.
  15. #endif
  16. #ifdef __cplusplus
  17. extern "C" {
  18. #endif
  19. /**
  20. * Add socket fd to the set *fdset if not yet present.
  21. * Enlarges the set if necessary.
  22. */
  23. #define NETSNMP_LARGE_FD_SET(fd, fdset) \
  24. netsnmp_large_fd_setfd(fd, fdset)
  25. /**
  26. * Remove socket fd from the set *fdset.
  27. * Do nothing if fd is not present in *fdset.
  28. * Do nothing if fd >= fdset->lfs_setsize.
  29. */
  30. #define NETSNMP_LARGE_FD_CLR(fd, fdset) \
  31. netsnmp_large_fd_clr(fd, fdset)
  32. /**
  33. * Test whether set *fdset contains socket fd.
  34. * Evaluates to zero (false) if fd >= fdset->lfs_setsize.
  35. */
  36. #define NETSNMP_LARGE_FD_ISSET(fd, fdset) \
  37. netsnmp_large_fd_is_set(fd, fdset)
  38. #if !defined(cygwin) && defined(HAVE_WINSOCK_H)
  39. /**
  40. * Number of bytes needed to store a number of file descriptors as a
  41. * struct fd_set.
  42. */
  43. #define NETSNMP_FD_SET_BYTES(setsize) \
  44. (sizeof(fd_set) + ((setsize) > FD_SETSIZE ? \
  45. ((setsize) - FD_SETSIZE) * sizeof(SOCKET) : 0))
  46. /** Remove all sockets from the set *fdset. */
  47. #define NETSNMP_LARGE_FD_ZERO(fdset) \
  48. do { (fdset)->lfs_setptr->fd_count = 0; } while(0)
  49. struct timeval;
  50. NETSNMP_IMPORT
  51. void netsnmp_large_fd_setfd( SOCKET fd, netsnmp_large_fd_set *fdset);
  52. NETSNMP_IMPORT
  53. void netsnmp_large_fd_clr( SOCKET fd, netsnmp_large_fd_set *fdset);
  54. NETSNMP_IMPORT
  55. int netsnmp_large_fd_is_set(SOCKET fd, netsnmp_large_fd_set *fdset);
  56. #else
  57. /**
  58. * Size of a single element of the array with file descriptor bitmasks.
  59. *
  60. * According to SUSv2, this array must have the name fds_bits. See also
  61. * <a href="http://www.opengroup.org/onlinepubs/007908775/xsh/systime.h.html">The Single UNIX Specification, Version 2, &lt;sys/time.h&gt;</a>.
  62. */
  63. #define NETSNMP_FD_MASK_SIZE sizeof(((fd_set*)0)->fds_bits[0])
  64. /** Number of bits in one element of the fd_set.fds_bits array. */
  65. #define NETSNMP_BITS_PER_FD_MASK (8 * NETSNMP_FD_MASK_SIZE)
  66. /** Number of elements needed for the fds_bits array. */
  67. #define NETSNMP_FD_SET_ELEM_COUNT(setsize) \
  68. (setsize + NETSNMP_BITS_PER_FD_MASK - 1) / NETSNMP_BITS_PER_FD_MASK
  69. /**
  70. * Number of bytes needed to store a number of file descriptors as a
  71. * struct fd_set.
  72. */
  73. #define NETSNMP_FD_SET_BYTES(setsize) \
  74. (sizeof(fd_set) + ((setsize) > FD_SETSIZE ? \
  75. NETSNMP_FD_SET_ELEM_COUNT((setsize) - FD_SETSIZE) \
  76. * NETSNMP_FD_MASK_SIZE : 0))
  77. /** Remove all file descriptors from the set *fdset. */
  78. #define NETSNMP_LARGE_FD_ZERO(fdset) \
  79. do { \
  80. memset((fdset)->lfs_setptr, 0, \
  81. NETSNMP_FD_SET_BYTES((fdset)->lfs_setsize)); \
  82. } while (0)
  83. void netsnmp_large_fd_setfd( int fd, netsnmp_large_fd_set *fdset);
  84. void netsnmp_large_fd_clr( int fd, netsnmp_large_fd_set *fdset);
  85. int netsnmp_large_fd_is_set(int fd, netsnmp_large_fd_set *fdset);
  86. #endif
  87. /**
  88. * Initialize a netsnmp_large_fd_set structure.
  89. *
  90. * Note: this function only initializes the lfs_setsize and lfs_setptr
  91. * members of netsnmp_large_fd_set, not the file descriptor set itself.
  92. * The file descriptor set must be initialized separately, e.g. via
  93. * NETSNMP_LARGE_FD_CLR().
  94. */
  95. NETSNMP_IMPORT
  96. void netsnmp_large_fd_set_init( netsnmp_large_fd_set *fdset, int setsize);
  97. /**
  98. * Modify the size of a file descriptor set and preserve the first
  99. * min(fdset->lfs_setsize, setsize) file descriptors.
  100. *
  101. * Returns 1 upon success or 0 if memory allocation failed.
  102. */
  103. int netsnmp_large_fd_set_resize( netsnmp_large_fd_set *fdset, int setsize);
  104. /**
  105. * Synchronous I/O multiplexing for large file descriptor sets.
  106. *
  107. * On POSIX systems, any file descriptor set with size below numfds will be
  108. * resized before invoking select().
  109. *
  110. * @see See also select(2) for more information.
  111. */
  112. NETSNMP_IMPORT
  113. int netsnmp_large_fd_set_select(int numfds, netsnmp_large_fd_set *readfds,
  114. netsnmp_large_fd_set *writefds,
  115. netsnmp_large_fd_set *exceptfds,
  116. struct timeval *timeout);
  117. /** Deallocate the memory allocated by netsnmp_large_fd_set_init. */
  118. NETSNMP_IMPORT
  119. void netsnmp_large_fd_set_cleanup(netsnmp_large_fd_set *fdset);
  120. /**
  121. * Copy an fd_set to a netsnmp_large_fd_set structure.
  122. *
  123. * @note dst must have been initialized before this function is called.
  124. */
  125. void netsnmp_copy_fd_set_to_large_fd_set(netsnmp_large_fd_set *dst,
  126. const fd_set *src);
  127. /**
  128. * Copy a netsnmp_large_fd_set structure into an fd_set.
  129. *
  130. * @return 0 upon success, -1 when copying fails because *src is too large to
  131. * fit into *dst.
  132. */
  133. int netsnmp_copy_large_fd_set_to_fd_set( fd_set *dst,
  134. const netsnmp_large_fd_set *src);
  135. #ifdef __cplusplus
  136. }
  137. #endif
  138. #endif /* LARGE_FD_SET_H */