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 int external_readfd[NUM_EXTERNAL_FDS], external_readfdlen = 0;
00011 int external_writefd[NUM_EXTERNAL_FDS], external_writefdlen = 0;
00012 int external_exceptfd[NUM_EXTERNAL_FDS], external_exceptfdlen = 0;
00013 void (*external_readfdfunc[NUM_EXTERNAL_FDS]) (int, void *);
00014 void (*external_writefdfunc[NUM_EXTERNAL_FDS]) (int, void *);
00015 void (*external_exceptfdfunc[NUM_EXTERNAL_FDS]) (int, void *);
00016 void *external_readfd_data[NUM_EXTERNAL_FDS];
00017 void *external_writefd_data[NUM_EXTERNAL_FDS];
00018 void *external_exceptfd_data[NUM_EXTERNAL_FDS];
00019
00020 static int external_fd_unregistered;
00021
00022
00023
00024
00025
00026 int
00027 register_readfd(int fd, void (*func) (int, void *), void *data)
00028 {
00029 if (external_readfdlen < NUM_EXTERNAL_FDS) {
00030 external_readfd[external_readfdlen] = fd;
00031 external_readfdfunc[external_readfdlen] = func;
00032 external_readfd_data[external_readfdlen] = data;
00033 external_readfdlen++;
00034 DEBUGMSGTL(("fd_event_manager:register_readfd", "registered fd %d\n", fd));
00035 return FD_REGISTERED_OK;
00036 } else {
00037 snmp_log(LOG_CRIT, "register_readfd: too many file descriptors\n");
00038 return FD_REGISTRATION_FAILED;
00039 }
00040 }
00041
00042
00043
00044
00045
00046 int
00047 register_writefd(int fd, void (*func) (int, void *), void *data)
00048 {
00049 if (external_writefdlen < NUM_EXTERNAL_FDS) {
00050 external_writefd[external_writefdlen] = fd;
00051 external_writefdfunc[external_writefdlen] = func;
00052 external_writefd_data[external_writefdlen] = data;
00053 external_writefdlen++;
00054 DEBUGMSGTL(("fd_event_manager:register_writefd", "registered fd %d\n", fd));
00055 return FD_REGISTERED_OK;
00056 } else {
00057 snmp_log(LOG_CRIT,
00058 "register_writefd: too many file descriptors\n");
00059 return FD_REGISTRATION_FAILED;
00060 }
00061 }
00062
00063
00064
00065
00066
00067 int
00068 register_exceptfd(int fd, void (*func) (int, void *), void *data)
00069 {
00070 if (external_exceptfdlen < NUM_EXTERNAL_FDS) {
00071 external_exceptfd[external_exceptfdlen] = fd;
00072 external_exceptfdfunc[external_exceptfdlen] = func;
00073 external_exceptfd_data[external_exceptfdlen] = data;
00074 external_exceptfdlen++;
00075 DEBUGMSGTL(("fd_event_manager:register_exceptfd", "registered fd %d\n", fd));
00076 return FD_REGISTERED_OK;
00077 } else {
00078 snmp_log(LOG_CRIT,
00079 "register_exceptfd: too many file descriptors\n");
00080 return FD_REGISTRATION_FAILED;
00081 }
00082 }
00083
00084
00085
00086
00087 int
00088 unregister_readfd(int fd)
00089 {
00090 int i, j;
00091
00092 for (i = 0; i < external_readfdlen; i++) {
00093 if (external_readfd[i] == fd) {
00094 external_readfdlen--;
00095 for (j = i; j < external_readfdlen; j++) {
00096 external_readfd[j] = external_readfd[j + 1];
00097 external_readfdfunc[j] = external_readfdfunc[j + 1];
00098 external_readfd_data[j] = external_readfd_data[j + 1];
00099 }
00100 DEBUGMSGTL(("fd_event_manager:unregister_readfd", "unregistered fd %d\n", fd));
00101 external_fd_unregistered = 1;
00102 return FD_UNREGISTERED_OK;
00103 }
00104 }
00105 return FD_NO_SUCH_REGISTRATION;
00106 }
00107
00108
00109
00110
00111 int
00112 unregister_writefd(int fd)
00113 {
00114 int i, j;
00115
00116 for (i = 0; i < external_writefdlen; i++) {
00117 if (external_writefd[i] == fd) {
00118 external_writefdlen--;
00119 for (j = i; j < external_writefdlen; j++) {
00120 external_writefd[j] = external_writefd[j + 1];
00121 external_writefdfunc[j] = external_writefdfunc[j + 1];
00122 external_writefd_data[j] = external_writefd_data[j + 1];
00123 }
00124 DEBUGMSGTL(("fd_event_manager:unregister_writefd", "unregistered fd %d\n", fd));
00125 external_fd_unregistered = 1;
00126 return FD_UNREGISTERED_OK;
00127 }
00128 }
00129 return FD_NO_SUCH_REGISTRATION;
00130 }
00131
00132
00133
00134
00135 int
00136 unregister_exceptfd(int fd)
00137 {
00138 int i, j;
00139
00140 for (i = 0; i < external_exceptfdlen; i++) {
00141 if (external_exceptfd[i] == fd) {
00142 external_exceptfdlen--;
00143 for (j = i; j < external_exceptfdlen; j++) {
00144 external_exceptfd[j] = external_exceptfd[j + 1];
00145 external_exceptfdfunc[j] = external_exceptfdfunc[j + 1];
00146 external_exceptfd_data[j] = external_exceptfd_data[j + 1];
00147 }
00148 DEBUGMSGTL(("fd_event_manager:unregister_exceptfd", "unregistered fd %d\n",
00149 fd));
00150 external_fd_unregistered = 1;
00151 return FD_UNREGISTERED_OK;
00152 }
00153 }
00154 return FD_NO_SUCH_REGISTRATION;
00155 }
00156
00157
00158
00159
00160 void netsnmp_external_event_info(int *numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
00161 {
00162 int i;
00163
00164 external_fd_unregistered = 0;
00165
00166 for (i = 0; i < external_readfdlen; i++) {
00167 FD_SET(external_readfd[i], readfds);
00168 if (external_readfd[i] >= *numfds)
00169 *numfds = external_readfd[i] + 1;
00170 }
00171 for (i = 0; i < external_writefdlen; i++) {
00172 FD_SET(external_writefd[i], writefds);
00173 if (external_writefd[i] >= *numfds)
00174 *numfds = external_writefd[i] + 1;
00175 }
00176 for (i = 0; i < external_exceptfdlen; i++) {
00177 FD_SET(external_exceptfd[i], exceptfds);
00178 if (external_exceptfd[i] >= *numfds)
00179 *numfds = external_exceptfd[i] + 1;
00180 }
00181 }
00182
00183
00184
00185
00186 void netsnmp_dispatch_external_events(int *count, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
00187 {
00188 int i;
00189 for (i = 0;
00190 *count && (i < external_readfdlen) && !external_fd_unregistered; i++) {
00191 if (FD_ISSET(external_readfd[i], readfds)) {
00192 DEBUGMSGTL(("fd_event_manager:netsnmp_dispatch_external_events",
00193 "readfd[%d] = %d\n", i, external_readfd[i]));
00194 external_readfdfunc[i] (external_readfd[i],
00195 external_readfd_data[i]);
00196 FD_CLR(external_readfd[i], readfds);
00197 (*count)--;
00198 }
00199 }
00200 for (i = 0;
00201 *count && (i < external_writefdlen) && !external_fd_unregistered; i++) {
00202 if (FD_ISSET(external_writefd[i], writefds)) {
00203 DEBUGMSGTL(("fd_event_manager:netsnmp_dispatch_external_events",
00204 "writefd[%d] = %d\n", i, external_writefd[i]));
00205 external_writefdfunc[i] (external_writefd[i],
00206 external_writefd_data[i]);
00207 FD_CLR(external_writefd[i], writefds);
00208 (*count)--;
00209 }
00210 }
00211 for (i = 0;
00212 *count && (i < external_exceptfdlen) && !external_fd_unregistered; i++) {
00213 if (FD_ISSET(external_exceptfd[i], exceptfds)) {
00214 DEBUGMSGTL(("fd_event_manager:netsnmp_dispatch_external_events",
00215 "exceptfd[%d] = %d\n", i, external_exceptfd[i]));
00216 external_exceptfdfunc[i] (external_exceptfd[i],
00217 external_exceptfd_data[i]);
00218 FD_CLR(external_exceptfd[i], exceptfds);
00219 (*count)--;
00220 }
00221 }
00222 }