]> jfr.im git - irc/rqf/shadowircd.git/blame - libratbox/src/ports.c
Fix up grammar in ShadowIRCd MOTD for great good!
[irc/rqf/shadowircd.git] / libratbox / src / ports.c
CommitLineData
b57f37fb
WP
1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * ports.c: Solaris ports compatible network routines.
4 *
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>
f030cae8 8 * Copyright (C) 2002-2004,2008 ircd-ratbox development team
b57f37fb
WP
9 * Copyright (C) 2005 Edward Brocklesby.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
24 * USA
25 *
b57f37fb
WP
26 */
27
28#include <libratbox_config.h>
29#include <ratbox_lib.h>
30#include <commio-int.h>
f030cae8 31#include <event-int.h>
b57f37fb
WP
32#if defined(HAVE_PORT_H) && (HAVE_PORT_CREATE)
33
34#include <port.h>
35
b57f37fb
WP
36#define PE_LENGTH 128
37
b57f37fb
WP
38static int pe;
39static struct timespec zero_timespec;
40
41static port_event_t *pelst; /* port buffer */
42static int pemax; /* max structs to buffer */
43
94b4fbf9 44int
f030cae8 45rb_setup_fd_ports(rb_fde_t *F)
b57f37fb 46{
94b4fbf9 47 return 0;
b57f37fb 48}
94b4fbf9 49
b57f37fb
WP
50/*
51 * rb_init_netio
52 *
53 * This is a needed exported function which will be called to initialise
54 * the network loop code.
55 */
f030cae8 56
b57f37fb
WP
57int
58rb_init_netio_ports(void)
59{
94b4fbf9
VY
60 if((pe = port_create()) < 0)
61 {
b57f37fb
WP
62 return errno;
63 }
64 pemax = getdtablesize();
65 pelst = rb_malloc(sizeof(port_event_t) * pemax);
66 zero_timespec.tv_sec = 0;
67 zero_timespec.tv_nsec = 0;
f030cae8
VY
68 rb_set_time();
69 return 0;
b57f37fb
WP
70}
71
72/*
73 * rb_setselect
74 *
75 * This is a needed exported function which will be called to register
76 * and deregister interest in a pending IO state for a given FD.
77 */
78void
94b4fbf9 79rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
b57f37fb
WP
80{
81 lrb_assert(IsFDOpen(F));
f030cae8 82 int old_flags = F->pflags;
b57f37fb 83
94b4fbf9
VY
84 if(type & RB_SELECT_READ)
85 {
b57f37fb
WP
86 F->read_handler = handler;
87 F->read_data = client_data;
88 }
94b4fbf9
VY
89 if(type & RB_SELECT_WRITE)
90 {
b57f37fb
WP
91 F->write_handler = handler;
92 F->write_data = client_data;
93 }
f030cae8
VY
94 F->pflags = 0;
95
96 if(F->read_handler != NULL)
97 F->pflags = POLLIN;
98 if(F->write_handler != NULL)
99 F->pflags |= POLLOUT;
100
101 if(old_flags == 0 && F->pflags == 0)
102 return;
103 else if(F->pflags <= 0)
104 {
105 port_dissociate(pe, PORT_SOURCE_FD, F->fd);
106 return;
107 }
108
109 port_associate(pe, PORT_SOURCE_FD, F->fd, F->pflags, F);
110
b57f37fb
WP
111}
112
113/*
114 * rb_select
115 *
116 * Called to do the new-style IO, courtesy of squid (like most of this
117 * new IO code). This routine handles the stuff we've hidden in
118 * rb_setselect and fd_table[] and calls callbacks for IO ready
119 * events.
120 */
121
122int
123rb_select_ports(long delay)
124{
94b4fbf9 125 int i, fd;
f030cae8 126 int nget = 1;
94b4fbf9 127 struct timespec poll_time;
f030cae8
VY
128 struct timespec *p = NULL;
129 struct ev_entry *ev;
b57f37fb 130
f030cae8
VY
131 if(delay >= 0)
132 {
133 poll_time.tv_sec = delay / 1000;
134 poll_time.tv_nsec = (delay % 1000) * 1000000;
135 p = &poll_time;
136 }
b57f37fb 137
f030cae8
VY
138
139 i = port_getn(pe, pelst, pemax, &nget, p);
b57f37fb
WP
140 rb_set_time();
141
94b4fbf9 142 if(i == -1)
b57f37fb
WP
143 return RB_OK;
144
94b4fbf9
VY
145 for(i = 0; i < nget; i++)
146 {
f030cae8 147 if(pelst[i].portev_source == PORT_SOURCE_FD)
94b4fbf9 148 {
b57f37fb
WP
149 fd = pelst[i].portev_object;
150 PF *hdl = NULL;
f030cae8
VY
151 rb_fde_t *F = pelst[i].portev_user;
152 if((pelst[i].portev_events & (POLLIN | POLLHUP | POLLERR)) && (hdl = F->read_handler))
94b4fbf9 153 {
b57f37fb
WP
154 F->read_handler = NULL;
155 hdl(F, F->read_data);
156 }
f030cae8 157 if((pelst[i].portev_events & (POLLOUT | POLLHUP | POLLERR)) && (hdl = F->write_handler))
94b4fbf9 158 {
b57f37fb
WP
159 F->write_handler = NULL;
160 hdl(F, F->write_data);
161 }
f030cae8
VY
162 } else if(pelst[i].portev_source == PORT_SOURCE_TIMER)
163 {
164 ev = (struct ev_entry *)pelst[i].portev_user;
165 rb_run_event(ev);
b57f37fb
WP
166 }
167 }
168 return RB_OK;
169}
170
f030cae8
VY
171int
172rb_ports_supports_event(void)
173{
174 return 1;
175};
176
177void
178rb_ports_init_event(void)
179{
180 return;
181}
182
183int
184rb_ports_sched_event(struct ev_entry *event, int when)
185{
186 timer_t *id;
187 struct sigevent ev;
188 port_notify_t not;
189 struct itimerspec ts;
190
191 event->comm_ptr = rb_malloc(sizeof(timer_t));
192 id = event->comm_ptr;
193
194 memset(&ev, 0, sizeof(ev));
195 ev.sigev_notify = SIGEV_PORT;
196 ev.sigev_value.sival_ptr = &not;
197
198 memset(&not, 0, sizeof(not));
199 not.portnfy_port = pe;
200 not.portnfy_user = event;
201
202 if(timer_create(CLOCK_REALTIME, &ev, id) < 0)
203 {
204 rb_lib_log("timer_create: %s\n", strerror(errno));
205 return 0;
206 }
207
208 memset(&ts, 0, sizeof(ts));
209 ts.it_value.tv_sec = when;
210 ts.it_value.tv_nsec = 0;
211 if(event->frequency != 0)
212 ts.it_interval = ts.it_value;
213
214 if(timer_settime(*id, 0, &ts, NULL) < 0)
215 {
216 rb_lib_log("timer_settime: %s\n", strerror(errno));
217 return 0;
218 }
219 return 1;
220}
221
222void
223rb_ports_unsched_event(struct ev_entry *event)
224{
225 timer_delete(*((timer_t *) event->comm_ptr));
226 rb_free(event->comm_ptr);
227 event->comm_ptr = NULL;
228}
b57f37fb 229#else /* ports not supported */
f030cae8
VY
230
231int
232rb_ports_supports_event(void)
233{
234 errno = ENOSYS;
235 return 0;
236}
237
238void
239rb_ports_init_event(void)
240{
241 return;
242}
243
244int
245rb_ports_sched_event(struct ev_entry *event, int when)
246{
247 errno = ENOSYS;
248 return -1;
249}
250
251void
252rb_ports_unsched_event(struct ev_entry *event)
253{
254 return;
255}
256
94b4fbf9 257int
b57f37fb
WP
258rb_init_netio_ports(void)
259{
260 return ENOSYS;
261}
262
263void
264rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
265{
94b4fbf9
VY
266 errno = ENOSYS;
267 return;
b57f37fb 268}
94b4fbf9 269
b57f37fb
WP
270int
271rb_select_ports(long delay)
272{
94b4fbf9
VY
273 errno = ENOSYS;
274 return -1;
b57f37fb 275}
94b4fbf9 276
b57f37fb
WP
277int
278rb_setup_fd_ports(rb_fde_t *F)
279{
94b4fbf9
VY
280 errno = ENOSYS;
281 return -1;
b57f37fb
WP
282}
283
94b4fbf9 284
b57f37fb 285#endif