00001
00002 #include <net-snmp/net-snmp-config.h>
00003 #ifdef HAVE_SYS_SELECT
00004 #include <sys/select.h>
00005 #endif
00006 #include <net-snmp/net-snmp-includes.h>
00007 #include <net-snmp/library/snmp_api.h>
00008 #include <net-snmp/library/fd_event_manager.h>
00009 #include <net-snmp/library/snmp_logging.h>
00010 #include <net-snmp/library/large_fd_set.h>
00011
00012
00013 int external_readfd[NUM_EXTERNAL_FDS], external_readfdlen = 0;
00014 int external_writefd[NUM_EXTERNAL_FDS], external_writefdlen = 0;
00015 int external_exceptfd[NUM_EXTERNAL_FDS], external_exceptfdlen = 0;
00016 void (*external_readfdfunc[NUM_EXTERNAL_FDS]) (int, void *);
00017 void (*external_writefdfunc[NUM_EXTERNAL_FDS]) (int, void *);
00018 void (*external_exceptfdfunc[NUM_EXTERNAL_FDS]) (int, void *);
00019 void *external_readfd_data[NUM_EXTERNAL_FDS];
00020 void *external_writefd_data[NUM_EXTERNAL_FDS];
00021 void *external_exceptfd_data[NUM_EXTERNAL_FDS];
00022
00023 static int external_fd_unregistered;
00024
00025
00026
00027
00028
00029 int
00030 register_readfd(int fd, void (*func) (int, void *), void *data)
00031 {
00032 if (external_readfdlen < NUM_EXTERNAL_FDS) {
00033 external_readfd[external_readfdlen] = fd;
00034 external_readfdfunc[external_readfdlen] = func;
00035 external_readfd_data[external_readfdlen] = data;
00036 external_readfdlen++;
00037 DEBUGMSGTL(("fd_event_manager:register_readfd", "registered fd %d\n", fd));
00038 return FD_REGISTERED_OK;
00039 } else {
00040 snmp_log(LOG_CRIT, "register_readfd: too many file descriptors\n");
00041 return FD_REGISTRATION_FAILED;
00042 }
00043 }
00044
00045
00046
00047
00048
00049 int
00050 register_writefd(int fd, void (*func) (int, void *), void *data)
00051 {
00052 if (external_writefdlen < NUM_EXTERNAL_FDS) {
00053 external_writefd[external_writefdlen] = fd;
00054 external_writefdfunc[external_writefdlen] = func;
00055 external_writefd_data[external_writefdlen] = data;
00056 external_writefdlen++;
00057 DEBUGMSGTL(("fd_event_manager:register_writefd", "registered fd %d\n", fd));
00058 return FD_REGISTERED_OK;
00059 } else {
00060 snmp_log(LOG_CRIT,
00061 "register_writefd: too many file descriptors\n");
00062 return FD_REGISTRATION_FAILED;
00063 }
00064 }
00065
00066
00067
00068
00069
00070 int
00071 register_exceptfd(int fd, void (*func) (int, void *), void *data)
00072 {
00073 if (external_exceptfdlen < NUM_EXTERNAL_FDS) {
00074 external_exceptfd[external_exceptfdlen] = fd;
00075 external_exceptfdfunc[external_exceptfdlen] = func;
00076 external_exceptfd_data[external_exceptfdlen] = data;
00077 external_exceptfdlen++;
00078 DEBUGMSGTL(("fd_event_manager:register_exceptfd", "registered fd %d\n", fd));
00079 return FD_REGISTERED_OK;
00080 } else {
00081 snmp_log(LOG_CRIT,
00082 "register_exceptfd: too many file descriptors\n");
00083 return FD_REGISTRATION_FAILED;
00084 }
00085 }
00086
00087
00088
00089
00090 int
00091 unregister_readfd(int fd)
00092 {
00093 int i, j;
00094
00095 for (i = 0; i < external_readfdlen; i++) {
00096 if (external_readfd[i] == fd) {
00097 external_readfdlen--;
00098 for (j = i; j < external_readfdlen; j++) {
00099 external_readfd[j] = external_readfd[j + 1];
00100 external_readfdfunc[j] = external_readfdfunc[j + 1];
00101 external_readfd_data[j] = external_readfd_data[j + 1];
00102 }
00103 DEBUGMSGTL(("fd_event_manager:unregister_readfd", "unregistered fd %d\n", fd));
00104 external_fd_unregistered = 1;
00105 return FD_UNREGISTERED_OK;
00106 }
00107 }
00108 return FD_NO_SUCH_REGISTRATION;
00109 }
00110
00111
00112
00113
00114 int
00115 unregister_writefd(int fd)
00116 {
00117 int i, j;
00118
00119 for (i = 0; i < external_writefdlen; i++) {
00120 if (external_writefd[i] == fd) {
00121 external_writefdlen--;
00122 for (j = i; j < external_writefdlen; j++) {
00123 external_writefd[j] = external_writefd[j + 1];
00124 external_writefdfunc[j] = external_writefdfunc[j + 1];
00125 external_writefd_data[j] = external_writefd_data[j + 1];
00126 }
00127 DEBUGMSGTL(("fd_event_manager:unregister_writefd", "unregistered fd %d\n", fd));
00128 external_fd_unregistered = 1;
00129 return FD_UNREGISTERED_OK;
00130 }
00131 }
00132 return FD_NO_SUCH_REGISTRATION;
00133 }
00134
00135
00136
00137
00138 int
00139 unregister_exceptfd(int fd)
00140 {
00141 int i, j;
00142
00143 for (i = 0; i < external_exceptfdlen; i++) {
00144 if (external_exceptfd[i] == fd) {
00145 external_exceptfdlen--;
00146 for (j = i; j < external_exceptfdlen; j++) {
00147 external_exceptfd[j] = external_exceptfd[j + 1];
00148 external_exceptfdfunc[j] = external_exceptfdfunc[j + 1];
00149 external_exceptfd_data[j] = external_exceptfd_data[j + 1];
00150 }
00151 DEBUGMSGTL(("fd_event_manager:unregister_exceptfd", "unregistered fd %d\n",
00152 fd));
00153 external_fd_unregistered = 1;
00154 return FD_UNREGISTERED_OK;
00155 }
00156 }
00157 return FD_NO_SUCH_REGISTRATION;
00158 }
00159
00160
00161
00162
00163 void netsnmp_external_event_info(int *numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
00164 {
00165 netsnmp_large_fd_set lreadfds;
00166 netsnmp_large_fd_set lwritefds;
00167 netsnmp_large_fd_set lexceptfds;
00168
00169 netsnmp_large_fd_set_init(&lreadfds, FD_SETSIZE);
00170 netsnmp_large_fd_set_init(&lwritefds, FD_SETSIZE);
00171 netsnmp_large_fd_set_init(&lexceptfds, FD_SETSIZE);
00172
00173 netsnmp_copy_fd_set_to_large_fd_set(&lreadfds, readfds);
00174 netsnmp_copy_fd_set_to_large_fd_set(&lwritefds, writefds);
00175 netsnmp_copy_fd_set_to_large_fd_set(&lexceptfds, exceptfds);
00176
00177 netsnmp_external_event_info2(numfds, &lreadfds, &lwritefds, &lexceptfds);
00178
00179 if (netsnmp_copy_large_fd_set_to_fd_set(readfds, &lreadfds) < 0
00180 || netsnmp_copy_large_fd_set_to_fd_set(writefds, &lwritefds) < 0
00181 || netsnmp_copy_large_fd_set_to_fd_set(exceptfds, &lexceptfds) < 0)
00182 {
00183 snmp_log(LOG_ERR,
00184 "Use netsnmp_external_event_info2() for processing"
00185 " large file descriptors");
00186 }
00187
00188 netsnmp_large_fd_set_cleanup(&lreadfds);
00189 netsnmp_large_fd_set_cleanup(&lwritefds);
00190 netsnmp_large_fd_set_cleanup(&lexceptfds);
00191 }
00192
00193 void netsnmp_external_event_info2(int *numfds,
00194 netsnmp_large_fd_set *readfds,
00195 netsnmp_large_fd_set *writefds,
00196 netsnmp_large_fd_set *exceptfds)
00197 {
00198 int i;
00199
00200 external_fd_unregistered = 0;
00201
00202 for (i = 0; i < external_readfdlen; i++) {
00203 NETSNMP_LARGE_FD_SET(external_readfd[i], readfds);
00204 if (external_readfd[i] >= *numfds)
00205 *numfds = external_readfd[i] + 1;
00206 }
00207 for (i = 0; i < external_writefdlen; i++) {
00208 NETSNMP_LARGE_FD_SET(external_writefd[i], writefds);
00209 if (external_writefd[i] >= *numfds)
00210 *numfds = external_writefd[i] + 1;
00211 }
00212 for (i = 0; i < external_exceptfdlen; i++) {
00213 NETSNMP_LARGE_FD_SET(external_exceptfd[i], exceptfds);
00214 if (external_exceptfd[i] >= *numfds)
00215 *numfds = external_exceptfd[i] + 1;
00216 }
00217 }
00218
00219
00220
00221
00222 void netsnmp_dispatch_external_events(int *count, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
00223 {
00224 netsnmp_large_fd_set lreadfds;
00225 netsnmp_large_fd_set lwritefds;
00226 netsnmp_large_fd_set lexceptfds;
00227
00228 netsnmp_large_fd_set_init(&lreadfds, FD_SETSIZE);
00229 netsnmp_large_fd_set_init(&lwritefds, FD_SETSIZE);
00230 netsnmp_large_fd_set_init(&lexceptfds, FD_SETSIZE);
00231
00232 netsnmp_copy_fd_set_to_large_fd_set(&lreadfds, readfds);
00233 netsnmp_copy_fd_set_to_large_fd_set(&lwritefds, writefds);
00234 netsnmp_copy_fd_set_to_large_fd_set(&lexceptfds, exceptfds);
00235
00236 netsnmp_dispatch_external_events2(count, &lreadfds, &lwritefds, &lexceptfds);
00237
00238 if (netsnmp_copy_large_fd_set_to_fd_set(readfds, &lreadfds) < 0
00239 || netsnmp_copy_large_fd_set_to_fd_set(writefds, &lwritefds) < 0
00240 || netsnmp_copy_large_fd_set_to_fd_set(exceptfds, &lexceptfds) < 0)
00241 {
00242 snmp_log(LOG_ERR,
00243 "Use netsnmp_dispatch_external_events2() for processing"
00244 " large file descriptors");
00245 }
00246
00247 netsnmp_large_fd_set_cleanup(&lreadfds);
00248 netsnmp_large_fd_set_cleanup(&lwritefds);
00249 netsnmp_large_fd_set_cleanup(&lexceptfds);
00250 }
00251
00252 void netsnmp_dispatch_external_events2(int *count,
00253 netsnmp_large_fd_set *readfds,
00254 netsnmp_large_fd_set *writefds,
00255 netsnmp_large_fd_set *exceptfds)
00256 {
00257 int i;
00258 for (i = 0;
00259 *count && (i < external_readfdlen) && !external_fd_unregistered; i++) {
00260 if (NETSNMP_LARGE_FD_ISSET(external_readfd[i], readfds)) {
00261 DEBUGMSGTL(("fd_event_manager:netsnmp_dispatch_external_events",
00262 "readfd[%d] = %d\n", i, external_readfd[i]));
00263 external_readfdfunc[i] (external_readfd[i],
00264 external_readfd_data[i]);
00265 NETSNMP_LARGE_FD_CLR(external_readfd[i], readfds);
00266 (*count)--;
00267 }
00268 }
00269 for (i = 0;
00270 *count && (i < external_writefdlen) && !external_fd_unregistered; i++) {
00271 if (NETSNMP_LARGE_FD_ISSET(external_writefd[i], writefds)) {
00272 DEBUGMSGTL(("fd_event_manager:netsnmp_dispatch_external_events",
00273 "writefd[%d] = %d\n", i, external_writefd[i]));
00274 external_writefdfunc[i] (external_writefd[i],
00275 external_writefd_data[i]);
00276 NETSNMP_LARGE_FD_CLR(external_writefd[i], writefds);
00277 (*count)--;
00278 }
00279 }
00280 for (i = 0;
00281 *count && (i < external_exceptfdlen) && !external_fd_unregistered; i++) {
00282 if (NETSNMP_LARGE_FD_ISSET(external_exceptfd[i], exceptfds)) {
00283 DEBUGMSGTL(("fd_event_manager:netsnmp_dispatch_external_events",
00284 "exceptfd[%d] = %d\n", i, external_exceptfd[i]));
00285 external_exceptfdfunc[i] (external_exceptfd[i],
00286 external_exceptfd_data[i]);
00287 NETSNMP_LARGE_FD_CLR(external_exceptfd[i], exceptfds);
00288 (*count)--;
00289 }
00290 }
00291 }