2 * IRC - Internet Relay Chat, common/bsd.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Computing Center
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)
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.
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.
23 #include <sys/socket.h> /* Needed for send() */
34 int writeb[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
37 RETSIGTYPE dummy(HANDLER_ARG(int UNUSED(sig)))
39 #ifndef HAVE_RELIABLE_SIGNALS
40 signal(SIGALRM, dummy);
41 signal(SIGPIPE, dummy);
42 #ifndef HPUX /* Only 9k/800 series require this,
43 but don't know how to.. */
45 signal(SIGWINCH, dummy);
52 act.sa_handler = dummy;
54 sigemptyset(&act.sa_mask);
55 sigaddset(&act.sa_mask, SIGALRM);
56 sigaddset(&act.sa_mask, SIGPIPE);
58 sigaddset(&act.sa_mask, SIGWINCH);
60 sigaction(SIGALRM, &act, (struct sigaction *)NULL);
61 sigaction(SIGPIPE, &act, (struct sigaction *)NULL);
63 sigaction(SIGWINCH, &act, (struct sigaction *)NULL);
71 * Attempt to send a sequence of bytes to the connection.
74 * < 0 Some fatal error occurred, (but not EWOULDBLOCK).
75 * This return is a request to close the socket and
78 * >= 0 No real error occurred, returns the number of
79 * bytes actually transferred. EWOULDBLOCK and other
80 * possibly similar conditions should be mapped to
81 * zero return. Upper level routine will have to
82 * decide what to do with those unwritten bytes...
84 * *NOTE* alarm calls have been preserved, so this should
85 * work equally well whether blocking or non-blocking
88 * We don't use blocking anymore, that is impossible with the
89 * net.loads today anyway. Commented out the alarms to save cpu.
92 int deliver_it(aClient *cptr, const char *str, int len)
95 aClient *acpt = cptr->acpt;
101 retval = netwrite(cptr->fd, str, len);
103 retval = send(cptr->fd, str, len, 0);
105 * Convert WOULDBLOCK to a return of "0 bytes moved". This
106 * should occur only if socket was non-blocking. Note, that
107 * all is Ok, if the 'write' just returns '0' instead of an
108 * error and errno=EWOULDBLOCK.
110 * ...now, would this work on VMS too? --msa
112 if (retval < 0 && (errno == EWOULDBLOCK || errno == EAGAIN ||
114 errno == ENOMEM || errno == ENOSR ||
119 cptr->flags |= FLAGS_BLOCKED;
124 gettimeofday(&cptr->lw, NULL);
126 cptr->flags &= ~FLAGS_BLOCKED;
134 Debug((DEBUG_ERROR, "write error (%s) to %s",
135 sys_errlist[errno], cptr->name));
137 else if (retval == 0)
139 else if (retval < 16)
141 else if (retval < 32)
143 else if (retval < 64)
145 else if (retval < 128)
147 else if (retval < 256)
149 else if (retval < 512)
151 else if (retval < 1024)
158 cptr->sendB += retval;
160 if (cptr->sendB > 1023)
162 cptr->sendK += (cptr->sendB >> 10);
163 cptr->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
167 acpt->sendB += retval;
168 if (acpt->sendB > 1023)
170 acpt->sendK += (acpt->sendB >> 10);
171 acpt->sendB &= 0x03ff;
174 else if (me.sendB > 1023)
176 me.sendK += (me.sendB >> 10);