Annotation of embedaddon/mtr/select.c, revision 1.1
1.1 ! misho 1: /*
! 2: mtr -- a network diagnostic tool
! 3: Copyright (C) 1997,1998 Matt Kimball
! 4:
! 5: This program is free software; you can redistribute it and/or modify
! 6: it under the terms of the GNU General Public License version 2 as
! 7: published by the Free Software Foundation.
! 8:
! 9: This program is distributed in the hope that it will be useful,
! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 12: GNU General Public License for more details.
! 13:
! 14: You should have received a copy of the GNU General Public License
! 15: along with this program; if not, write to the Free Software
! 16: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! 17: */
! 18:
! 19: #include <config.h>
! 20: #include <sys/types.h>
! 21: #include <sys/time.h>
! 22: #include <stdlib.h>
! 23: #include <stdio.h>
! 24: #include <unistd.h>
! 25: #include <time.h>
! 26: #include <sys/select.h>
! 27: #include <string.h>
! 28: #include <math.h>
! 29: #include <errno.h>
! 30:
! 31: #include "mtr.h"
! 32: #include "display.h"
! 33: #include "dns.h"
! 34: #include "net.h"
! 35: #ifndef NO_IPINFO
! 36: #include "asn.h"
! 37: #endif
! 38:
! 39: extern int Interactive;
! 40: extern int MaxPing;
! 41: extern int ForceMaxPing;
! 42: extern float WaitTime;
! 43: double dnsinterval;
! 44: extern int mtrtype;
! 45:
! 46: static struct timeval intervaltime;
! 47: int display_offset = 0;
! 48:
! 49:
! 50: void select_loop(void) {
! 51: fd_set readfd;
! 52: fd_set writefd;
! 53: int anyset = 0;
! 54: int maxfd = 0;
! 55: int dnsfd, netfd;
! 56: #ifdef ENABLE_IPV6
! 57: int dnsfd6;
! 58: #endif
! 59: int NumPing = 0;
! 60: int paused = 0;
! 61: struct timeval lasttime, thistime, selecttime;
! 62: int dt;
! 63: int rv;
! 64:
! 65: gettimeofday(&lasttime, NULL);
! 66:
! 67: while(1) {
! 68: dt = calc_deltatime (WaitTime);
! 69: intervaltime.tv_sec = dt / 1000000;
! 70: intervaltime.tv_usec = dt % 1000000;
! 71:
! 72: FD_ZERO(&readfd);
! 73: FD_ZERO(&writefd);
! 74:
! 75: maxfd = 0;
! 76:
! 77: if(Interactive) {
! 78: FD_SET(0, &readfd);
! 79: maxfd = 1;
! 80: }
! 81:
! 82: #ifdef ENABLE_IPV6
! 83: if (dns) {
! 84: dnsfd6 = dns_waitfd6();
! 85: FD_SET(dnsfd6, &readfd);
! 86: if(dnsfd6 >= maxfd) maxfd = dnsfd6 + 1;
! 87: } else
! 88: dnsfd6 = 0;
! 89: #endif
! 90: if (dns) {
! 91: dnsfd = dns_waitfd();
! 92: FD_SET(dnsfd, &readfd);
! 93: if(dnsfd >= maxfd) maxfd = dnsfd + 1;
! 94: } else
! 95: dnsfd = 0;
! 96:
! 97: netfd = net_waitfd();
! 98: FD_SET(netfd, &readfd);
! 99: if(netfd >= maxfd) maxfd = netfd + 1;
! 100:
! 101: if (mtrtype == IPPROTO_TCP)
! 102: net_add_fds(&writefd, &maxfd);
! 103:
! 104: do {
! 105: if(anyset || paused) {
! 106: selecttime.tv_sec = 0;
! 107: selecttime.tv_usec = 0;
! 108:
! 109: rv = select(maxfd, (void *)&readfd, &writefd, NULL, &selecttime);
! 110:
! 111: } else {
! 112: if(Interactive) display_redraw();
! 113:
! 114: gettimeofday(&thistime, NULL);
! 115:
! 116: if(thistime.tv_sec > lasttime.tv_sec + intervaltime.tv_sec ||
! 117: (thistime.tv_sec == lasttime.tv_sec + intervaltime.tv_sec &&
! 118: thistime.tv_usec >= lasttime.tv_usec + intervaltime.tv_usec)) {
! 119: lasttime = thistime;
! 120: if(NumPing >= MaxPing && (!Interactive || ForceMaxPing))
! 121: return;
! 122: if (net_send_batch())
! 123: NumPing++;
! 124: }
! 125:
! 126: selecttime.tv_usec = (thistime.tv_usec - lasttime.tv_usec);
! 127: selecttime.tv_sec = (thistime.tv_sec - lasttime.tv_sec);
! 128: if (selecttime.tv_usec < 0) {
! 129: --selecttime.tv_sec;
! 130: selecttime.tv_usec += 1000000;
! 131: }
! 132: selecttime.tv_usec = intervaltime.tv_usec - selecttime.tv_usec;
! 133: selecttime.tv_sec = intervaltime.tv_sec - selecttime.tv_sec;
! 134: if (selecttime.tv_usec < 0) {
! 135: --selecttime.tv_sec;
! 136: selecttime.tv_usec += 1000000;
! 137: }
! 138:
! 139: if (dns) {
! 140: if ((selecttime.tv_sec > (time_t)dnsinterval) ||
! 141: ((selecttime.tv_sec == (time_t)dnsinterval) &&
! 142: (selecttime.tv_usec > ((time_t)(dnsinterval * 1000000) % 1000000)))) {
! 143: selecttime.tv_sec = (time_t)dnsinterval;
! 144: selecttime.tv_usec = (time_t)(dnsinterval * 1000000) % 1000000;
! 145: }
! 146: }
! 147:
! 148: rv = select(maxfd, (void *)&readfd, NULL, NULL, &selecttime);
! 149: }
! 150: } while ((rv < 0) && (errno == EINTR));
! 151:
! 152: if (rv < 0) {
! 153: perror ("Select failed");
! 154: exit (1);
! 155: }
! 156: anyset = 0;
! 157:
! 158: /* Have we got new packets back? */
! 159: if(FD_ISSET(netfd, &readfd)) {
! 160: net_process_return();
! 161: anyset = 1;
! 162: }
! 163:
! 164: if (dns) {
! 165: /* Handle any pending resolver events */
! 166: dnsinterval = WaitTime;
! 167: dns_events(&dnsinterval);
! 168: }
! 169:
! 170: /* Have we finished a nameservice lookup? */
! 171: #ifdef ENABLE_IPV6
! 172: if(dns && FD_ISSET(dnsfd6, &readfd)) {
! 173: dns_ack6();
! 174: anyset = 1;
! 175: }
! 176: #endif
! 177: if(dns && FD_ISSET(dnsfd, &readfd)) {
! 178: dns_ack();
! 179: anyset = 1;
! 180: }
! 181:
! 182: /* Has a key been pressed? */
! 183: if(FD_ISSET(0, &readfd)) {
! 184: switch (display_keyaction()) {
! 185: case ActionQuit:
! 186: return;
! 187: break;
! 188: case ActionReset:
! 189: net_reset();
! 190: break;
! 191: case ActionDisplay:
! 192: display_mode = (display_mode+1) % 3;
! 193: break;
! 194: case ActionClear:
! 195: display_clear();
! 196: break;
! 197: case ActionPause:
! 198: paused=1;
! 199: break;
! 200: case ActionResume:
! 201: paused=0;
! 202: break;
! 203: case ActionMPLS:
! 204: enablempls = !enablempls;
! 205: display_clear();
! 206: break;
! 207: case ActionDNS:
! 208: if (dns) {
! 209: use_dns = !use_dns;
! 210: display_clear();
! 211: }
! 212: break;
! 213: #ifndef NO_IPINFO
! 214: case ActionII:
! 215: if (ipinfo_no >= 0) {
! 216: ipinfo_no++;
! 217: if (ipinfo_no > ipinfo_max)
! 218: ipinfo_no = 0;
! 219: }
! 220: break;
! 221: case ActionAS:
! 222: if (ipinfo_no >= 0)
! 223: ipinfo_no = ipinfo_no?0:ipinfo_max;
! 224: break;
! 225: #endif
! 226:
! 227: case ActionScrollDown:
! 228: display_offset += 5;
! 229: break;
! 230: case ActionScrollUp:
! 231: display_offset -= 5;
! 232: if (display_offset < 0) {
! 233: display_offset = 0;
! 234: }
! 235: break;
! 236: }
! 237: anyset = 1;
! 238: }
! 239:
! 240: /* Check for activity on open sockets */
! 241: if (mtrtype == IPPROTO_TCP)
! 242: net_process_fds(&writefd);
! 243: }
! 244: return;
! 245: }
! 246:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>