net-snmp
5.4.1
|
00001 /* UNIT: File Descriptor (FD) Event Manager */ 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 * Register a given fd for read events. Call callback when events 00024 * are received. 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 * Register a given fd for write events. Call callback when events 00044 * are received. 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 * Register a given fd for exception events. Call callback when events 00065 * are received. 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 * Unregister a given fd for read events. 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 * Unregister a given fd for read events. 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 * Unregister a given fd for exception events. 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 * NET-SNMP External Event Info 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 * NET-SNMP Dispatch External Events 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 }