]>
jfr.im git - solanum.git/blob - libcharybdis/ports.c
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
11 * Copyright (C) 2007 River Tarnell
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 * $Id: ports.c 3366 2007-04-03 09:57:53Z nenolod $
42 #include "sprintf_irc.h"
47 static int comm_init(void);
48 static void comm_deinit(void);
50 static int comm_select_impl(unsigned long delay
);
51 static void comm_setselect_impl(int fd
, unsigned int type
, PF
* handler
, void *client_data
, time_t timeout
);
53 static void pe_update_events(fde_t
*, short, PF
*);
55 static struct timespec zero_timespec
;
57 static port_event_t
*pelst
; /* port buffer */
58 static int pemax
; /* max structs to buffer */
61 pe_update_events(fde_t
* F
, short filter
, PF
* handler
)
63 PF
*cur_handler
= NULL
;
65 if (filter
== POLLRDNORM
)
66 cur_handler
= F
->read_handler
;
67 else if (filter
== POLLWRNORM
)
68 cur_handler
= F
->write_handler
;
70 if (!cur_handler
&& handler
)
71 port_associate(pe
, PORT_SOURCE_FD
, F
->fd
, filter
, F
);
72 else if (cur_handler
&& !handler
)
73 port_dissociate(pe
, PORT_SOURCE_FD
, F
->fd
);
76 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
77 /* Public functions */
83 * This is a needed exported function which will be called to initialise
84 * the network loop code.
89 if((pe
= port_create()) < 0) {
90 ilog(L_MAIN
, "init_netio: Couldn't open port fd!\n");
91 exit(115); /* Whee! */
93 pemax
= getdtablesize();
94 pelst
= MyMalloc(sizeof(port_event_t
) * pemax
);
95 zero_timespec
.tv_sec
= 0;
96 zero_timespec
.tv_nsec
= 0;
104 * This is a needed exported function which will be called to register
105 * and deregister interest in a pending IO state for a given FD.
108 comm_setselect(int fd
, unsigned int type
, PF
* handler
,
109 void *client_data
, time_t timeout
)
111 fde_t
*F
= &fd_table
[fd
];
113 s_assert(F
->flags
.open
);
115 if (type
& COMM_SELECT_READ
) {
116 pe_update_events(F
, POLLRDNORM
, handler
);
117 F
->read_handler
= handler
;
118 F
->read_data
= client_data
;
120 if (type
& COMM_SELECT_WRITE
) {
121 pe_update_events(F
, POLLWRNORM
, handler
);
122 F
->write_handler
= handler
;
123 F
->write_data
= client_data
;
130 * Called to do the new-style IO, courtesy of squid (like most of this
131 * new IO code). This routine handles the stuff we've hidden in
132 * ircd_setselect and fd_table[] and calls callbacks for IO ready
137 comm_select(unsigned long delay
)
140 unsigned int nget
= 1;
141 struct timespec poll_time
;
143 poll_time
.tv_sec
= delay
/ 1000;
144 poll_time
.tv_nsec
= (delay
% 1000) * 1000000;
146 i
= port_getn(pe
, pelst
, pemax
, &nget
, &poll_time
);
152 for (i
= 0; i
< nget
; i
++)
157 switch(pelst
[i
].portev_source
)
160 fd
= pelst
[i
].portev_object
;
163 if ((pelst
[i
].portev_events
& POLLRDNORM
) && (hdl
= F
->read_handler
)) {
164 F
->read_handler
= NULL
;
165 hdl(fd
, F
->read_data
);
167 if (F
->flags
.open
== 0)
170 if ((pelst
[i
].portev_events
& POLLWRNORM
) && (hdl
= F
->write_handler
)) {
171 F
->write_handler
= NULL
;
172 hdl(fd
, F
->write_data
);