home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / in4wjcxu / other / irc / common / bsd.c next >
Encoding:
C/C++ Source or Header  |  1996-08-14  |  4.5 KB  |  179 lines

  1. /************************************************************************
  2.  *   IRC - Internet Relay Chat, common/bsd.c
  3.  *   Copyright (C) 1990 Jarkko Oikarinen and
  4.  *                      University of Oulu, Computing Center
  5.  *
  6.  *   This program is free software; you can redistribute it and/or modify
  7.  *   it under the terms of the GNU General Public License as published by
  8.  *   the Free Software Foundation; either version 1, or (at your option)
  9.  *   any later version.
  10.  *
  11.  *   This program is distributed in the hope that it will be useful,
  12.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *   GNU General Public License for more details.
  15.  *
  16.  *   You should have received a copy of the GNU General Public License
  17.  *   along with this program; if not, write to the Free Software
  18.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #ifndef lint
  22. static  char sccsid[] = "@(#)bsd.c    2.14 1/30/94 (C) 1988 University of Oulu, \
  23. Computing Center and Jarkko Oikarinen";
  24. #endif
  25.  
  26. #include "struct.h"
  27. #include "common.h"
  28. #include "sys.h"
  29. #include "h.h"
  30. #include <signal.h>
  31.  
  32. extern    int errno; /* ...seems that errno.h doesn't define this everywhere */
  33. extern    char    *sys_errlist[];
  34.  
  35. #ifdef DEBUGMODE
  36. int    writecalls = 0, writeb[10] = {0,0,0,0,0,0,0,0,0,0};
  37. #endif
  38. VOIDSIG dummy()
  39. {
  40. #ifndef HAVE_RELIABLE_SIGNALS
  41.     (void)signal(SIGALRM, dummy);
  42.     (void)signal(SIGPIPE, dummy);
  43. #ifndef HPUX    /* Only 9k/800 series require this, but don't know how to.. */
  44. # ifdef SIGWINCH
  45.     (void)signal(SIGWINCH, dummy);
  46. # endif
  47. #endif
  48. #else
  49. # ifdef POSIX_SIGNALS
  50.     struct  sigaction       act;
  51.  
  52.     act.sa_handler = dummy;
  53.     act.sa_flags = 0;
  54.     (void)sigemptyset(&act.sa_mask);
  55.     (void)sigaddset(&act.sa_mask, SIGALRM);
  56.     (void)sigaddset(&act.sa_mask, SIGPIPE);
  57. #  ifdef SIGWINCH
  58.     (void)sigaddset(&act.sa_mask, SIGWINCH);
  59. #  endif
  60.     (void)sigaction(SIGALRM, &act, (struct sigaction *)NULL);
  61.     (void)sigaction(SIGPIPE, &act, (struct sigaction *)NULL);
  62. #  ifdef SIGWINCH
  63.     (void)sigaction(SIGWINCH, &act, (struct sigaction *)NULL);
  64. #  endif
  65. # endif
  66. #endif
  67. }
  68.  
  69.  
  70. /*
  71. ** deliver_it
  72. **    Attempt to send a sequence of bytes to the connection.
  73. **    Returns
  74. **
  75. **    < 0    Some fatal error occurred, (but not EWOULDBLOCK).
  76. **        This return is a request to close the socket and
  77. **        clean up the link.
  78. **    
  79. **    >= 0    No real error occurred, returns the number of
  80. **        bytes actually transferred. EWOULDBLOCK and other
  81. **        possibly similar conditions should be mapped to
  82. **        zero return. Upper level routine will have to
  83. **        decide what to do with those unwritten bytes...
  84. **
  85. **    *NOTE*    alarm calls have been preserved, so this should
  86. **        work equally well whether blocking or non-blocking
  87. **        mode is used...
  88. */
  89. int    deliver_it(cptr, str, len)
  90. aClient *cptr;
  91. int    len;
  92. char    *str;
  93.     {
  94.     int    retval;
  95.     aClient    *acpt = cptr->acpt;
  96.  
  97. #ifdef    DEBUGMODE
  98.     writecalls++;
  99. #endif
  100.     (void)alarm(WRITEWAITDELAY);
  101. #ifdef VMS
  102.     retval = netwrite(cptr->fd, str, len);
  103. #else
  104.     retval = send(cptr->fd, str, len, 0);
  105.     /*
  106.     ** Convert WOULDBLOCK to a return of "0 bytes moved". This
  107.     ** should occur only if socket was non-blocking. Note, that
  108.     ** all is Ok, if the 'write' just returns '0' instead of an
  109.     ** error and errno=EWOULDBLOCK.
  110.     **
  111.     ** ...now, would this work on VMS too? --msa
  112.     */
  113.     if (retval < 0 && (errno == EWOULDBLOCK || errno == EAGAIN ||
  114.                errno == ENOBUFS))
  115.         {
  116.         retval = 0;
  117.         cptr->flags |= FLAGS_BLOCKED;
  118.         }
  119.     else if (retval > 0)
  120.         {
  121. #ifdef    pyr
  122.         (void)gettimeofday(&cptr->lw, NULL);
  123. #endif
  124.         cptr->flags &= ~FLAGS_BLOCKED;
  125.         }
  126.  
  127. #endif
  128.     (void )alarm(0);
  129. #ifdef DEBUGMODE
  130.     if (retval < 0) {
  131.         writeb[0]++;
  132.         Debug((DEBUG_ERROR,"write error (%s) to %s",
  133.             sys_errlist[errno], cptr->name));
  134.     } else if (retval == 0)
  135.         writeb[1]++;
  136.     else if (retval < 16)
  137.         writeb[2]++;
  138.     else if (retval < 32)
  139.         writeb[3]++;
  140.     else if (retval < 64)
  141.         writeb[4]++;
  142.     else if (retval < 128)
  143.         writeb[5]++;
  144.     else if (retval < 256)
  145.         writeb[6]++;
  146.     else if (retval < 512)
  147.         writeb[7]++;
  148.     else if (retval < 1024)
  149.         writeb[8]++;
  150.     else
  151.         writeb[9]++;
  152. #endif
  153.     if (retval > 0)
  154.         {
  155.         cptr->sendB += retval;
  156.         me.sendB += retval;
  157.         if (cptr->sendB > 1023)
  158.             {
  159.             cptr->sendK += (cptr->sendB >> 10);
  160.             cptr->sendB &= 0x03ff;    /* 2^10 = 1024, 3ff = 1023 */
  161.             }
  162.         if (acpt != &me)
  163.             {
  164.             acpt->sendB += retval;
  165.             if (acpt->sendB > 1023)
  166.                 {
  167.                 acpt->sendK += (acpt->sendB >> 10);
  168.                 acpt->sendB &= 0x03ff;
  169.                 }
  170.             }
  171.         else if (me.sendB > 1023)
  172.             {
  173.             me.sendK += (me.sendB >> 10);
  174.             me.sendB &= 0x03ff;
  175.             }
  176.         }
  177.     return(retval);
  178. }
  179.