2 * charybdis: A slightly useful ircd.
3 * ports.c: Solaris ports 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-2004 ircd-ratbox development team
9 * Copyright (C) 2005 Edward Brocklesby.
10 * Copyright (C) 2005 William Pitcock and Jilles Tjoelker
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 * $Id: ports.c 181 2006-12-18 02:56:07Z beu $
38 static void pe_update_events(fde_t
*, short, PF
*);
40 static struct timespec zero_timespec
;
42 static port_event_t
*pelst
; /* port buffer */
43 static int pemax
; /* max structs to buffer */
53 pe_update_events(fde_t
* F
, short filter
, PF
* handler
)
55 PF
*cur_handler
= NULL
;
57 if (filter
== POLLRDNORM
)
58 cur_handler
= F
->read_handler
;
59 else if (filter
== POLLWRNORM
)
60 cur_handler
= F
->write_handler
;
62 if (!cur_handler
&& handler
)
63 port_associate(pe
, PORT_SOURCE_FD
, F
->fd
, filter
, F
);
64 else if (cur_handler
&& !handler
)
65 port_dissociate(pe
, PORT_SOURCE_FD
, F
->fd
);
68 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
69 /* Public functions */
75 * This is a needed exported function which will be called to initialise
76 * the network loop code.
81 if((pe
= port_create()) < 0) {
82 libseven_log("init_netio: Couldn't open port fd!\n");
83 exit(115); /* Whee! */
85 pemax
= getdtablesize();
86 pelst
= MyMalloc(sizeof(port_event_t
) * pemax
);
87 zero_timespec
.tv_sec
= 0;
88 zero_timespec
.tv_nsec
= 0;
94 * This is a needed exported function which will be called to register
95 * and deregister interest in a pending IO state for a given FD.
98 ircd_setselect(int fd
, fdlist_t list
, unsigned int type
, PF
* handler
,
101 fde_t
*F
= &fd_table
[fd
];
103 s_assert(F
->flags
.open
);
105 /* Update the list, even though we're not using it .. */
108 if(type
& IRCD_SELECT_READ
) {
109 pe_update_events(F
, POLLRDNORM
, handler
);
110 F
->read_handler
= handler
;
111 F
->read_data
= client_data
;
113 if(type
& IRCD_SELECT_WRITE
) {
114 pe_update_events(F
, POLLWRNORM
, handler
);
115 F
->write_handler
= handler
;
116 F
->write_data
= client_data
;
123 * Called to do the new-style IO, courtesy of squid (like most of this
124 * new IO code). This routine handles the stuff we've hidden in
125 * ircd_setselect and fd_table[] and calls callbacks for IO ready
130 ircd_select(unsigned long delay
)
134 struct timespec poll_time
;
135 struct timer_data
*tdata
;
137 poll_time
.tv_sec
= delay
/ 1000;
138 poll_time
.tv_nsec
= (delay
% 1000) * 1000000;
140 i
= port_getn(pe
, pelst
, pemax
, &nget
, &poll_time
);
146 for (i
= 0; i
< nget
; i
++) {
147 switch(pelst
[i
].portev_source
) {
149 fd
= pelst
[i
].portev_object
;
151 fde_t
*F
= &fd_table
[fd
];
153 if ((pelst
[i
].portev_events
& POLLRDNORM
) && (hdl
= F
->read_handler
)) {
154 F
->read_handler
= NULL
;
155 hdl(fd
, F
->read_data
);
157 if ((pelst
[i
].portev_events
& POLLWRNORM
) && (hdl
= F
->write_handler
)) {
158 F
->write_handler
= NULL
;
159 hdl(fd
, F
->write_data
);
163 case PORT_SOURCE_TIMER
:
164 tdata
= pelst
[i
].portev_user
;
165 tdata
->td_cb(tdata
->td_udata
);
167 if (!tdata
->td_repeat
)