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