31 |
|
#include <sys/socket.h> |
32 |
|
#include <netinet/in.h> |
33 |
|
#include <arpa/inet.h> |
34 |
+ |
#include <poll.h> |
35 |
|
|
36 |
|
#ifdef TIME_WITH_SYS_TIME |
37 |
|
# include <sys/time.h> |
98 |
|
static struct bopm_sockaddr IRC_SVR; /* Sock Address Struct for IRC server */ |
99 |
|
static struct bopm_ircaddr IRC_LOCAL; /* Sock Address Struct for Bind */ |
100 |
|
|
100 |
– |
static fd_set IRC_READ_FDSET; /* fd_set for IRC (read) data for select()*/ |
101 |
– |
static struct timeval IRC_TIMEOUT; /* timeval struct for select() timeout */ |
102 |
– |
|
101 |
|
static time_t IRC_LAST = 0; /* Last full line of data from irc server*/ |
102 |
|
static time_t IRC_LASTRECONNECT = 0; /* Time of last reconnection */ |
103 |
|
|
134 |
|
void |
135 |
|
irc_cycle(void) |
136 |
|
{ |
137 |
+ |
static struct pollfd pfd; |
138 |
+ |
|
139 |
|
if (IRC_FD <= 0) |
140 |
|
{ |
141 |
|
/* Initialise negative cache. */ |
150 |
|
return; /* In case connect() immediately failed */ |
151 |
|
} |
152 |
|
|
153 |
< |
IRC_TIMEOUT.tv_sec = 0; |
154 |
< |
|
155 |
< |
/* Block .025 seconds to avoid excessive CPU use on select(). */ |
156 |
< |
IRC_TIMEOUT.tv_usec = 25000; |
153 |
> |
pfd.fd = IRC_FD; |
154 |
> |
pfd.events = POLLIN; |
155 |
|
|
156 |
< |
FD_ZERO(&IRC_READ_FDSET); |
157 |
< |
FD_SET(IRC_FD, &IRC_READ_FDSET); |
160 |
< |
|
161 |
< |
switch (select((IRC_FD + 1), &IRC_READ_FDSET, 0, 0, &IRC_TIMEOUT)) |
156 |
> |
/* Block .025 seconds to avoid excessive CPU use on poll(). */ |
157 |
> |
switch (poll(&pfd, 1, 25)) |
158 |
|
{ |
159 |
+ |
case 0: |
160 |
|
case -1: |
164 |
– |
return; |
165 |
– |
break; |
166 |
– |
case 0: |
161 |
|
break; |
162 |
|
default: |
163 |
|
/* Check if IRC data is available. */ |
164 |
< |
if (FD_ISSET(IRC_FD, &IRC_READ_FDSET)) |
164 |
> |
if (pfd.revents & POLLIN) |
165 |
|
irc_read(); |
166 |
|
|
167 |
|
break; |
215 |
|
|
216 |
|
if (IRC_FD == -1) |
217 |
|
{ |
218 |
< |
switch (errno) |
225 |
< |
{ |
226 |
< |
case EINVAL: |
227 |
< |
case EPROTONOSUPPORT: |
228 |
< |
log_printf("IRC -> socket(): SOCK_STREAM is not supported on this domain"); |
229 |
< |
break; |
230 |
< |
case ENFILE: |
231 |
< |
log_printf("IRC -> socket(): Not enough free file descriptors to allocate IRC socket"); |
232 |
< |
break; |
233 |
< |
case EMFILE: |
234 |
< |
log_printf("IRC -> socket(): Process table overflow when requesting file descriptor"); |
235 |
< |
break; |
236 |
< |
case EACCES: |
237 |
< |
log_printf("IRC -> socket(): Permission denied to create socket of type SOCK_STREAM"); |
238 |
< |
break; |
239 |
< |
case ENOMEM: |
240 |
< |
log_printf("IRC -> socket(): Insufficient memory to allocate socket"); |
241 |
< |
break; |
242 |
< |
default: |
243 |
< |
log_printf("IRC -> socket(): Unknown error allocating socket"); |
244 |
< |
break; |
245 |
< |
} |
246 |
< |
|
218 |
> |
log_printf("IRC -> socket(): error creating socket: %s", strerror(errno)); |
219 |
|
exit(EXIT_FAILURE); |
220 |
|
} |
221 |
|
|
238 |
|
|
239 |
|
if (bindret) |
240 |
|
{ |
241 |
< |
switch (errno) |
270 |
< |
{ |
271 |
< |
case EACCES: |
272 |
< |
log_printf("IRC -> bind(): No access to bind to %s", IRCItem->vhost); |
273 |
< |
break; |
274 |
< |
default: |
275 |
< |
log_printf("IRC -> bind(): Error binding to %s (%d)", IRCItem->vhost, errno); |
276 |
< |
break; |
277 |
< |
} |
278 |
< |
|
241 |
> |
log_printf("IRC -> bind(): error binding to %s: %s", IRCItem->vhost, strerror(errno)); |
242 |
|
exit(EXIT_FAILURE); |
243 |
|
} |
244 |
|
} |
277 |
|
if (send(IRC_FD, buf, len, 0) == -1) |
278 |
|
{ |
279 |
|
/* Return of -1 indicates error sending data; we reconnect. */ |
280 |
< |
log_printf("IRC -> Error sending data to server\n"); |
280 |
> |
log_printf("IRC -> Error sending data to server: %s", strerror(errno)); |
281 |
|
irc_reconnect(); |
282 |
|
} |
283 |
|
} |