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>