Remove spy hooks.
[seven.git] / libseven / select.c
blobe6de1c7fb03bf4a40dfd226deed7b904e10c7af3
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * select.c: select() compatible network routines.
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
8 * Copyright (C) 2002-2005 ircd-ratbox development team
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * USA
25 * $Id: select.c 181 2006-12-18 02:56:07Z beu $
28 #include "config.h"
30 #include "libseven.h"
32 #if HARD_FDLIMIT_ >= FD_SETSIZE
33 #error HARD_FDLIMIT_ must be less than FD_SETSIZE(try using poll instead of select)
34 #endif
36 * Note that this is only a single list - multiple lists is kinda pointless
37 * under select because the list size is a function of the highest FD :-)
38 * -- adrian
41 fd_set select_readfds;
42 fd_set select_writefds;
45 * You know, I'd rather have these local to comm_select but for some
46 * reason my gcc decides that I can't modify them at all..
47 * -- adrian
49 fd_set tmpreadfds;
50 fd_set tmpwritefds;
52 static void select_update_selectfds(int fd, short event, PF * handler);
54 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
55 /* Private functions */
58 * set and clear entries in the select array ..
60 static void
61 select_update_selectfds(int fd, short event, PF * handler)
63 /* Update the read / write set */
64 if(event & COMM_SELECT_READ)
66 if(handler)
67 FD_SET(fd, &select_readfds);
68 else
69 FD_CLR(fd, &select_readfds);
71 if(event & COMM_SELECT_WRITE)
73 if(handler)
74 FD_SET(fd, &select_writefds);
75 else
76 FD_CLR(fd, &select_writefds);
81 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
82 /* Public functions */
86 * init_netio
88 * This is a needed exported function which will be called to initialise
89 * the network loop code.
91 void
92 init_netio(void)
94 FD_ZERO(&select_readfds);
95 FD_ZERO(&select_writefds);
99 * comm_setselect
101 * This is a needed exported function which will be called to register
102 * and deregister interest in a pending IO state for a given FD.
104 void
105 comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
106 void *client_data, time_t timeout)
108 fde_t *F = &fd_table[fd];
109 s_assert(fd >= 0);
110 s_assert(F->flags.open);
112 if(type & COMM_SELECT_READ)
114 F->read_handler = handler;
115 F->read_data = client_data;
116 select_update_selectfds(fd, COMM_SELECT_READ, handler);
118 if(type & COMM_SELECT_WRITE)
120 F->write_handler = handler;
121 F->write_data = client_data;
122 select_update_selectfds(fd, COMM_SELECT_WRITE, handler);
124 if(timeout)
125 F->timeout = CurrentTime + (timeout / 1000);
129 * Check all connections for new connections and input data that is to be
130 * processed. Also check for connections with data queued and whether we can
131 * write it out.
135 * comm_select
137 * Do IO events
141 comm_select(unsigned long delay)
143 int num;
144 int fd;
145 PF *hdl;
146 fde_t *F;
147 struct timeval to;
149 /* Copy over the read/write sets so we don't have to rebuild em */
150 memcpy(&tmpreadfds, &select_readfds, sizeof(fd_set));
151 memcpy(&tmpwritefds, &select_writefds, sizeof(fd_set));
153 for (;;)
155 to.tv_sec = 0;
156 to.tv_usec = delay * 1000;
157 num = select(highest_fd + 1, &tmpreadfds, &tmpwritefds, NULL, &to);
158 if(num >= 0)
159 break;
160 if(ignoreErrno(errno))
161 continue;
162 set_time();
163 /* error! */
164 return -1;
165 /* NOTREACHED */
167 set_time();
169 if(num == 0)
170 return 0;
172 /* XXX we *could* optimise by falling out after doing num fds ... */
173 for (fd = 0; fd < highest_fd + 1; fd++)
175 F = &fd_table[fd];
177 if(FD_ISSET(fd, &tmpreadfds))
179 hdl = F->read_handler;
180 F->read_handler = NULL;
181 if(hdl)
182 hdl(fd, F->read_data);
185 if(F->flags.open == 0)
186 continue; /* Read handler closed us..go on */
188 if(FD_ISSET(fd, &tmpwritefds))
190 hdl = F->write_handler;
191 F->write_handler = NULL;
192 if(hdl)
193 hdl(fd, F->write_data);
196 if(F->read_handler == NULL)
197 select_update_selectfds(fd, COMM_SELECT_READ, NULL);
198 if(F->write_handler == NULL)
199 select_update_selectfds(fd, COMM_SELECT_WRITE, NULL);
201 return 0;