[BACK]Return to sys_bsd.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / telnet

Diff for /src/usr.bin/telnet/sys_bsd.c between version 1.15 and 1.16

version 1.15, 2013/04/21 09:51:24 version 1.16, 2014/07/19 23:50:38
Line 48 
Line 48 
 #define TELNET_FD_NET   2  #define TELNET_FD_NET   2
 #define TELNET_FD_NUM   3  #define TELNET_FD_NUM   3
   
 #ifndef USE_TERMIO  
 struct  tchars otc = { 0 }, ntc = { 0 };  
 struct  ltchars oltc = { 0 }, nltc = { 0 };  
 struct  sgttyb ottyb = { 0 }, nttyb = { 0 };  
 int     olmode = 0;  
 # define cfgetispeed(ptr)       (ptr)->sg_ispeed  
 # define cfgetospeed(ptr)       (ptr)->sg_ospeed  
 # define old_tc ottyb  
   
 #else   /* USE_TERMIO */  
 struct  termios old_tc = { 0 };  struct  termios old_tc = { 0 };
 extern struct termios new_tc;  extern struct termios new_tc;
   
 # ifndef        TCSANOW  
 #  ifdef TCSETS  
 #   define      TCSANOW         TCSETS  
 #   define      TCSADRAIN       TCSETSW  
 #   define      tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)  
 #  else  
 #   ifdef TCSETA  
 #    define     TCSANOW         TCSETA  
 #    define     TCSADRAIN       TCSETAW  
 #    define     tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)  
 #   else  
 #    define     TCSANOW         TIOCSETA  
 #    define     TCSADRAIN       TIOCSETAW  
 #    define     tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)  
 #   endif  
 #  endif  
 #  define       tcsetattr(f, a, t) ioctl(f, a, (char *)t)  
 #  define       cfgetospeed(ptr)        ((ptr)->c_cflag&CBAUD)  
 #  ifdef CIBAUD  
 #   define      cfgetispeed(ptr)        (((ptr)->c_cflag&CIBAUD) >> IBSHIFT)  
 #  else  
 #   define      cfgetispeed(ptr)        cfgetospeed(ptr)  
 #  endif  
 # endif /* TCSANOW */  
 # ifdef sysV88  
 # define TIOCFLUSH TC_PX_DRAIN  
 # endif  
 #endif  /* USE_TERMIO */  
   
     void      void
 init_sys()  init_sys()
 {  {
Line 208 
Line 169 
     void      void
 TerminalSaveState()  TerminalSaveState()
 {  {
 #ifndef USE_TERMIO  
     ioctl(0, TIOCGETP, (char *)&ottyb);  
     ioctl(0, TIOCGETC, (char *)&otc);  
     ioctl(0, TIOCGLTC, (char *)&oltc);  
     ioctl(0, TIOCLGET, (char *)&olmode);  
   
     ntc = otc;  
     nltc = oltc;  
     nttyb = ottyb;  
   
 #else   /* USE_TERMIO */  
     tcgetattr(0, &old_tc);      tcgetattr(0, &old_tc);
   
     new_tc = old_tc;      new_tc = old_tc;
Line 244 
Line 194 
 #ifndef VSTATUS  #ifndef VSTATUS
     termAytChar = CONTROL('T');      termAytChar = CONTROL('T');
 #endif  #endif
 #endif  /* USE_TERMIO */  
 }  }
   
     cc_t *      cc_t *
Line 260 
Line 209 
     case SLC_XON:       return(&termStartChar);      case SLC_XON:       return(&termStartChar);
     case SLC_XOFF:      return(&termStopChar);      case SLC_XOFF:      return(&termStopChar);
     case SLC_FORW1:     return(&termForw1Char);      case SLC_FORW1:     return(&termForw1Char);
 #ifdef  USE_TERMIO  
     case SLC_FORW2:     return(&termForw2Char);      case SLC_FORW2:     return(&termForw2Char);
 # ifdef VDISCARD  # ifdef VDISCARD
     case SLC_AO:        return(&termFlushChar);      case SLC_AO:        return(&termFlushChar);
Line 280 
Line 228 
 # ifdef VSTATUS  # ifdef VSTATUS
     case SLC_AYT:       return(&termAytChar);      case SLC_AYT:       return(&termAytChar);
 # endif  # endif
 #endif  
   
     case SLC_SYNCH:      case SLC_SYNCH:
     case SLC_BRK:      case SLC_BRK:
Line 293 
Line 240 
     void      void
 TerminalDefaultChars()  TerminalDefaultChars()
 {  {
 #ifndef USE_TERMIO  
     ntc = otc;  
     nltc = oltc;  
     nttyb.sg_kill = ottyb.sg_kill;  
     nttyb.sg_erase = ottyb.sg_erase;  
 #else   /* USE_TERMIO */  
     memmove(new_tc.c_cc, old_tc.c_cc, sizeof(old_tc.c_cc));      memmove(new_tc.c_cc, old_tc.c_cc, sizeof(old_tc.c_cc));
 # ifndef        VDISCARD  # ifndef        VDISCARD
     termFlushChar = CONTROL('O');      termFlushChar = CONTROL('O');
Line 321 
Line 262 
 # ifndef        VSTATUS  # ifndef        VSTATUS
     termAytChar = CONTROL('T');      termAytChar = CONTROL('T');
 # endif  # endif
 #endif  /* USE_TERMIO */  
 }  }
   
 #ifdef notdef  
 void  
 TerminalRestoreState()  
 {  
 }  
 #endif  
   
 /*  /*
  * TerminalNewMode - set up terminal to a specific mode.   * TerminalNewMode - set up terminal to a specific mode.
  *      MODE_ECHO: do local terminal echo   *      MODE_ECHO: do local terminal echo
Line 365 
Line 298 
     int f;      int f;
 {  {
     static int prevmode = 0;      static int prevmode = 0;
 #ifndef USE_TERMIO  
     struct tchars tc;  
     struct ltchars ltc;  
     struct sgttyb sb;  
     int lmode;  
 #else   /* USE_TERMIO */  
     struct termios tmp_tc;      struct termios tmp_tc;
 #endif  /* USE_TERMIO */  
     int onoff;      int onoff;
     int old;      int old;
     cc_t esc;      cc_t esc;
Line 387 
Line 313 
      * left to write out, it returns -1 if it couldn't do       * left to write out, it returns -1 if it couldn't do
      * anything at all, otherwise it returns 1 + the number       * anything at all, otherwise it returns 1 + the number
      * of characters left to write.       * of characters left to write.
 #ifndef USE_TERMIO  
      * We would really like ask the kernel to wait for the output  
      * to drain, like we can do with the TCSADRAIN, but we don't have  
      * that option.  The only ioctl that waits for the output to  
      * drain, TIOCSETP, also flushes the input queue, which is NOT  
      * what we want (TIOCSETP is like TCSADFLUSH).  
 #endif  
      */       */
     old = ttyflush(SYNCHing|flushout);      old = ttyflush(SYNCHing|flushout);
     if (old < 0 || old > 1) {      if (old < 0 || old > 1) {
 #ifdef  USE_TERMIO  
         tcgetattr(tin, &tmp_tc);          tcgetattr(tin, &tmp_tc);
 #endif  /* USE_TERMIO */  
         do {          do {
             /*              /*
              * Wait for data to drain, then flush again.               * Wait for data to drain, then flush again.
              */               */
 #ifdef  USE_TERMIO  
             tcsetattr(tin, TCSADRAIN, &tmp_tc);              tcsetattr(tin, TCSADRAIN, &tmp_tc);
 #endif  /* USE_TERMIO */  
             old = ttyflush(SYNCHing|flushout);              old = ttyflush(SYNCHing|flushout);
         } while (old < 0 || old > 1);          } while (old < 0 || old > 1);
     }      }
   
     old = prevmode;      old = prevmode;
     prevmode = f&~MODE_FORCE;      prevmode = f&~MODE_FORCE;
 #ifndef USE_TERMIO  
     sb = nttyb;  
     tc = ntc;  
     ltc = nltc;  
     lmode = olmode;  
 #else  
     tmp_tc = new_tc;      tmp_tc = new_tc;
 #endif  
   
     if (f&MODE_ECHO) {      if (f&MODE_ECHO) {
 #ifndef USE_TERMIO  
         sb.sg_flags |= ECHO;  
 #else  
         tmp_tc.c_lflag |= ECHO;          tmp_tc.c_lflag |= ECHO;
         tmp_tc.c_oflag |= ONLCR;          tmp_tc.c_oflag |= ONLCR;
         if (crlf)          if (crlf)
                 tmp_tc.c_iflag |= ICRNL;                  tmp_tc.c_iflag |= ICRNL;
 #endif  
     } else {      } else {
 #ifndef USE_TERMIO  
         sb.sg_flags &= ~ECHO;  
 #else  
         tmp_tc.c_lflag &= ~ECHO;          tmp_tc.c_lflag &= ~ECHO;
         tmp_tc.c_oflag &= ~ONLCR;          tmp_tc.c_oflag &= ~ONLCR;
 # ifdef notdef  
         if (crlf)  
                 tmp_tc.c_iflag &= ~ICRNL;  
 # endif  
 #endif  
     }      }
   
     if ((f&MODE_FLOW) == 0) {      if ((f&MODE_FLOW) == 0) {
 #ifndef USE_TERMIO  
         tc.t_startc = _POSIX_VDISABLE;  
         tc.t_stopc = _POSIX_VDISABLE;  
 #else  
         tmp_tc.c_iflag &= ~(IXOFF|IXON);        /* Leave the IXANY bit alone */          tmp_tc.c_iflag &= ~(IXOFF|IXON);        /* Leave the IXANY bit alone */
     } else {      } else {
         if (restartany < 0) {          if (restartany < 0) {
Line 459 
Line 351 
                 tmp_tc.c_iflag |= IXOFF|IXON;                  tmp_tc.c_iflag |= IXOFF|IXON;
                 tmp_tc.c_iflag &= ~IXANY;                  tmp_tc.c_iflag &= ~IXANY;
         }          }
 #endif  
     }      }
   
     if ((f&MODE_TRAPSIG) == 0) {      if ((f&MODE_TRAPSIG) == 0) {
 #ifndef USE_TERMIO  
         tc.t_intrc = _POSIX_VDISABLE;  
         tc.t_quitc = _POSIX_VDISABLE;  
         tc.t_eofc = _POSIX_VDISABLE;  
         ltc.t_suspc = _POSIX_VDISABLE;  
         ltc.t_dsuspc = _POSIX_VDISABLE;  
 #else  
         tmp_tc.c_lflag &= ~ISIG;          tmp_tc.c_lflag &= ~ISIG;
 #endif  
         localchars = 0;          localchars = 0;
     } else {      } else {
 #ifdef  USE_TERMIO  
         tmp_tc.c_lflag |= ISIG;          tmp_tc.c_lflag |= ISIG;
 #endif  
         localchars = 1;          localchars = 1;
     }      }
   
     if (f&MODE_EDIT) {      if (f&MODE_EDIT) {
 #ifndef USE_TERMIO  
         sb.sg_flags &= ~CBREAK;  
         sb.sg_flags |= CRMOD;  
 #else  
         tmp_tc.c_lflag |= ICANON;          tmp_tc.c_lflag |= ICANON;
 #endif  
     } else {      } else {
 #ifndef USE_TERMIO  
         sb.sg_flags |= CBREAK;  
         if (f&MODE_ECHO)  
             sb.sg_flags |= CRMOD;  
         else  
             sb.sg_flags &= ~CRMOD;  
 #else  
         tmp_tc.c_lflag &= ~ICANON;          tmp_tc.c_lflag &= ~ICANON;
         tmp_tc.c_iflag &= ~ICRNL;          tmp_tc.c_iflag &= ~ICRNL;
         tmp_tc.c_cc[VMIN] = 1;          tmp_tc.c_cc[VMIN] = 1;
         tmp_tc.c_cc[VTIME] = 0;          tmp_tc.c_cc[VTIME] = 0;
 #endif  
     }      }
   
     if ((f&(MODE_EDIT|MODE_TRAPSIG)) == 0) {      if ((f&(MODE_EDIT|MODE_TRAPSIG)) == 0) {
 #ifndef USE_TERMIO  
         ltc.t_lnextc = _POSIX_VDISABLE;  
 #else  
         tmp_tc.c_lflag &= ~IEXTEN;          tmp_tc.c_lflag &= ~IEXTEN;
 #endif  
     }      }
   
     if (f&MODE_SOFT_TAB) {      if (f&MODE_SOFT_TAB) {
 #ifndef USE_TERMIO  
         sb.sg_flags |= XTABS;  
 #else  
 # ifdef OXTABS  # ifdef OXTABS
         tmp_tc.c_oflag |= OXTABS;          tmp_tc.c_oflag |= OXTABS;
 # endif  # endif
Line 521 
Line 382 
         tmp_tc.c_oflag &= ~TABDLY;          tmp_tc.c_oflag &= ~TABDLY;
         tmp_tc.c_oflag |= TAB3;          tmp_tc.c_oflag |= TAB3;
 # endif  # endif
 #endif  
     } else {      } else {
 #ifndef USE_TERMIO  
         sb.sg_flags &= ~XTABS;  
 #else  
 # ifdef OXTABS  # ifdef OXTABS
         tmp_tc.c_oflag &= ~OXTABS;          tmp_tc.c_oflag &= ~OXTABS;
 # endif  # endif
 # ifdef TABDLY  # ifdef TABDLY
         tmp_tc.c_oflag &= ~TABDLY;          tmp_tc.c_oflag &= ~TABDLY;
 # endif  # endif
 #endif  
     }      }
   
     if (f&MODE_LIT_ECHO) {      if (f&MODE_LIT_ECHO) {
 #ifndef USE_TERMIO  
         lmode &= ~LCTLECH;  
 #else  
 # ifdef ECHOCTL  # ifdef ECHOCTL
         tmp_tc.c_lflag &= ~ECHOCTL;          tmp_tc.c_lflag &= ~ECHOCTL;
 # endif  # endif
 #endif  
     } else {      } else {
 #ifndef USE_TERMIO  
         lmode |= LCTLECH;  
 #else  
 # ifdef ECHOCTL  # ifdef ECHOCTL
         tmp_tc.c_lflag |= ECHOCTL;          tmp_tc.c_lflag |= ECHOCTL;
 # endif  # endif
 #endif  
     }      }
   
     if (f == -1) {      if (f == -1) {
         onoff = 0;          onoff = 0;
     } else {      } else {
 #ifndef USE_TERMIO  
         if (f & MODE_OUTBIN)  
                 lmode |= LLITOUT;  
         else  
                 lmode &= ~LLITOUT;  
   
         if (f & MODE_INBIN)          if (f & MODE_INBIN)
                 lmode |= LPASS8;  
         else  
                 lmode &= ~LPASS8;  
 #else  
         if (f & MODE_INBIN)  
                 tmp_tc.c_iflag &= ~ISTRIP;                  tmp_tc.c_iflag &= ~ISTRIP;
         else          else
                 tmp_tc.c_iflag |= ISTRIP;                  tmp_tc.c_iflag |= ISTRIP;
Line 584 
Line 421 
                 tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);                  tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);
                 tmp_tc.c_oflag |= OPOST;                  tmp_tc.c_oflag |= OPOST;
         }          }
 #endif  
         onoff = 1;          onoff = 1;
     }      }
   
Line 595 
Line 431 
 #ifdef  SIGINFO  #ifdef  SIGINFO
         (void) signal(SIGINFO, ayt);          (void) signal(SIGINFO, ayt);
 #endif  #endif
 #if     defined(USE_TERMIO) && defined(NOKERNINFO)  #if     defined(NOKERNINFO)
         tmp_tc.c_lflag |= NOKERNINFO;          tmp_tc.c_lflag |= NOKERNINFO;
 #endif  #endif
         /*          /*
Line 604 
Line 440 
          * to process it because it will be processed when the           * to process it because it will be processed when the
          * user attempts to read it, not when we send it.           * user attempts to read it, not when we send it.
          */           */
 #ifndef USE_TERMIO  
         ltc.t_dsuspc = _POSIX_VDISABLE;  
 #else  
 # ifdef VDSUSP  # ifdef VDSUSP
         tmp_tc.c_cc[VDSUSP] = (cc_t)(_POSIX_VDISABLE);          tmp_tc.c_cc[VDSUSP] = (cc_t)(_POSIX_VDISABLE);
 # endif  # endif
 #endif  
 #ifdef  USE_TERMIO  
         /*          /*
          * If the VEOL character is already set, then use VEOL2,           * If the VEOL character is already set, then use VEOL2,
          * otherwise use VEOL.           * otherwise use VEOL.
Line 629 
Line 460 
                     tmp_tc.c_cc[VEOL2] = esc;                      tmp_tc.c_cc[VEOL2] = esc;
 # endif  # endif
         }          }
 #else  
         if (tc.t_brkc == (cc_t)(_POSIX_VDISABLE))  
                 tc.t_brkc = esc;  
 #endif  
     } else {      } else {
 #ifdef  SIGTSTP  #ifdef  SIGTSTP
         sigset_t mask;          sigset_t mask;
Line 648 
Line 475 
         sigaddset(&mask, SIGTSTP);          sigaddset(&mask, SIGTSTP);
         sigprocmask(SIG_UNBLOCK, &mask, NULL);          sigprocmask(SIG_UNBLOCK, &mask, NULL);
 #endif  /* SIGTSTP */  #endif  /* SIGTSTP */
 #ifndef USE_TERMIO  
         ltc = oltc;  
         tc = otc;  
         sb = ottyb;  
         lmode = olmode;  
 #else  
         tmp_tc = old_tc;          tmp_tc = old_tc;
 #endif  
     }      }
 #ifndef USE_TERMIO  
     ioctl(tin, TIOCLSET, (char *)&lmode);  
     ioctl(tin, TIOCSLTC, (char *)&ltc);  
     ioctl(tin, TIOCSETC, (char *)&tc);  
     ioctl(tin, TIOCSETN, (char *)&sb);  
 #else  
     if (tcsetattr(tin, TCSADRAIN, &tmp_tc) < 0)      if (tcsetattr(tin, TCSADRAIN, &tmp_tc) < 0)
         tcsetattr(tin, TCSANOW, &tmp_tc);          tcsetattr(tin, TCSANOW, &tmp_tc);
 #endif  
   
 #if     (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR))  
 # if    !defined(sysV88)  
     ioctl(tin, FIONBIO, (char *)&onoff);      ioctl(tin, FIONBIO, (char *)&onoff);
     ioctl(tout, FIONBIO, (char *)&onoff);      ioctl(tout, FIONBIO, (char *)&onoff);
 # endif  
 #endif  /* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */  
 #if     defined(TN3270)  
     if (noasynchtty == 0) {  
         ioctl(tin, FIOASYNC, (char *)&onoff);  
     }  
 #endif  /* defined(TN3270) */  
   
 }  }
   
 /*  /*
Line 809 
Line 612 
     ioctl(fd, FIONBIO, (char *)&onoff);      ioctl(fd, FIONBIO, (char *)&onoff);
 }  }
   
 #if     defined(TN3270)  
     void  
 NetSigIO(fd, onoff)  
     int fd;  
     int onoff;  
 {  
     ioctl(fd, FIOASYNC, (char *)&onoff);        /* hear about input */  
 }  
   
     void  
 NetSetPgrp(fd)  
     int fd;  
 {  
     pid_t myPid;  
   
     myPid = getpid();  
     fcntl(fd, F_SETOWN, myPid);  
 }  
 #endif  /*defined(TN3270)*/  
   
 /*  /*
  * Various signal handling routines.   * Various signal handling routines.
Line 920 
Line 704 
     void      void
 sys_telnet_init()  sys_telnet_init()
 {  {
       int one = 1;
   
     (void) signal(SIGINT, intr);      (void) signal(SIGINT, intr);
     (void) signal(SIGQUIT, intr2);      (void) signal(SIGQUIT, intr2);
     (void) signal(SIGPIPE, deadpeer);      (void) signal(SIGPIPE, deadpeer);
Line 937 
Line 723 
   
     NetNonblockingIO(net, 1);      NetNonblockingIO(net, 1);
   
 #if     defined(TN3270)      if (setsockopt(net, SOL_SOCKET, SO_OOBINLINE, &one, sizeof(one)) == -1) {
     if (noasynchnet == 0) {                     /* DBX can't handle! */          perror("setsockopt");
         NetSigIO(net, 1);  
         NetSetPgrp(net);  
     }      }
 #endif  /* defined(TN3270) */  
   
 #if     defined(SO_OOBINLINE)  
     if (SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1) == -1) {  
         perror("SetSockOpt");  
     }  
 #endif  /* defined(SO_OOBINLINE) */  
 }  }
   
 /*  /*
Line 1010 
Line 787 
             if (errno == EINTR) {              if (errno == EINTR) {
                 return 0;                  return 0;
             }              }
 #           if defined(TN3270)  
                     /*  
                      * we can get EBADF if we were in transparent  
                      * mode, and the transcom process died.  
                     */  
             if (errno == EBADF) {  
                 return 0;  
             }  
 #           endif /* defined(TN3270) */  
                     /* I don't like this, does it ever happen? */                      /* I don't like this, does it ever happen? */
             printf("sleep(5) from telnet, after poll\r\n");              printf("sleep(5) from telnet, after poll\r\n");
             sleep(5);              sleep(5);
Line 1041 
Line 809 
         int canread;          int canread;
   
         canread = ring_empty_consecutive(&netiring);          canread = ring_empty_consecutive(&netiring);
 #if     !defined(SO_OOBINLINE)  
             /*  
              * In 4.2 (and some early 4.3) systems, the  
              * OOB indication and data handling in the kernel  
              * is such that if two separate TCP Urgent requests  
              * come in, one byte of TCP data will be overlaid.  
              * This is fatal for Telnet, but we try to live  
              * with it.  
              *  
              * In addition, in 4.2 (and...), a special protocol  
              * is needed to pick up the TCP Urgent data in  
              * the correct sequence.  
              *  
              * What we do is:  if we think we are in urgent  
              * mode, we look to see if we are "at the mark".  
              * If we are, we do an OOB receive.  If we run  
              * this twice, we will do the OOB receive twice,  
              * but the second will fail, since the second  
              * time we were "at the mark", but there wasn't  
              * any data there (the kernel doesn't reset  
              * "at the mark" until we do a normal read).  
              * Once we've read the OOB data, we go ahead  
              * and do normal reads.  
              *  
              * There is also another problem, which is that  
              * since the OOB byte we read doesn't put us  
              * out of OOB state, and since that byte is most  
              * likely the TELNET DM (data mark), we would  
              * stay in the TELNET SYNCH (SYNCHing) state.  
              * So, clocks to the rescue.  If we've "just"  
              * received a DM, then we test for the  
              * presence of OOB data when the receive OOB  
              * fails (and AFTER we did the normal mode read  
              * to clear "at the mark").  
              */  
         if (SYNCHing) {  
             int atmark;  
             static int bogus_oob = 0, first = 1;  
   
             ioctl(net, SIOCATMARK, (char *)&atmark);  
             if (atmark) {  
                 c = recv(net, netiring.supply, canread, MSG_OOB);  
                 if ((c == -1) && (errno == EINVAL)) {  
                     c = recv(net, netiring.supply, canread, 0);  
                     if (clocks.didnetreceive < clocks.gotDM) {  
                         SYNCHing = stilloob(net);  
                     }  
                 } else if (first && c > 0) {  
                     /*  
                      * Bogosity check.  Systems based on 4.2BSD  
                      * do not return an error if you do a second  
                      * recv(MSG_OOB).  So, we do one.  If it  
                      * succeeds and returns exactly the same  
                      * data, then assume that we are running  
                      * on a broken system and set the bogus_oob  
                      * flag.  (If the data was different, then  
                      * we probably got some valid new data, so  
                      * increment the count...)  
                      */  
                     int i;  
                     i = recv(net, netiring.supply + c, canread - c, MSG_OOB);  
                     if (i == c &&  
                          memcmp(netiring.supply, netiring.supply + c, i) == 0) {  
                         bogus_oob = 1;  
                         first = 0;  
                     } else if (i < 0) {  
                         bogus_oob = 0;  
                         first = 0;  
                     } else  
                         c += i;  
                 }  
                 if (bogus_oob && c > 0) {  
                     int i;  
                     /*  
                      * Bogosity.  We have to do the read  
                      * to clear the atmark to get out of  
                      * an infinate loop.  
                      */  
                     i = read(net, netiring.supply + c, canread - c);  
                     if (i > 0)  
                         c += i;  
                 }  
             } else {  
                 c = recv(net, netiring.supply, canread, 0);  
             }  
         } else {  
             c = recv(net, netiring.supply, canread, 0);  
         }  
         settimer(didnetreceive);  
 #else   /* !defined(SO_OOBINLINE) */  
         c = recv(net, (char *)netiring.supply, canread, 0);          c = recv(net, (char *)netiring.supply, canread, 0);
 #endif  /* !defined(SO_OOBINLINE) */  
         if (c < 0 && errno == EWOULDBLOCK) {          if (c < 0 && errno == EWOULDBLOCK) {
             c = 0;              c = 0;
         } else if (c <= 0) {          } else if (c <= 0) {

Legend:
Removed from v.1.15  
changed lines
  Added in v.1.16