/* * ircd-ratbox: A slightly useful ircd. * ports.c: Solaris ports compatible network routines. * * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center * Copyright (C) 1996-2002 Hybrid Development Team * Copyright (C) 2001 Adrian Chadd * Copyright (C) 2002-2004 ircd-ratbox development team * Copyright (C) 2005 Edward Brocklesby. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA * * $Id: ports.c 25038 2008-01-23 16:03:08Z androsyn $ */ #include #include #include #if defined(HAVE_PORT_H) && (HAVE_PORT_CREATE) #include #define PE_LENGTH 128 static void pe_update_events(rb_fde_t *, short, PF *); static int pe; static struct timespec zero_timespec; static port_event_t *pelst; /* port buffer */ static int pemax; /* max structs to buffer */ int rb_setup_fd_ports(int fd) { return 0; } static void pe_update_events(rb_fde_t * F, short filter, PF * handler) { PF *cur_handler = NULL; if (filter == POLLRDNORM) cur_handler = F->read_handler; else if (filter == POLLWRNORM) cur_handler = F->write_handler; if (!cur_handler && handler) port_associate(pe, PORT_SOURCE_FD, F->fd, filter, F); else if (cur_handler && !handler) port_dissociate(pe, PORT_SOURCE_FD, F->fd); } /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ /* Public functions */ /* * rb_init_netio * * This is a needed exported function which will be called to initialise * the network loop code. */ int rb_init_netio_ports(void) { if((pe = port_create()) < 0) { return errno; } pemax = getdtablesize(); pelst = rb_malloc(sizeof(port_event_t) * pemax); zero_timespec.tv_sec = 0; zero_timespec.tv_nsec = 0; } /* * rb_setselect * * This is a needed exported function which will be called to register * and deregister interest in a pending IO state for a given FD. */ void rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data) { lrb_assert(IsFDOpen(F)); /* Update the list, even though we're not using it .. */ if(type & RB_SELECT_READ) { pe_update_events(F, POLLRDNORM, handler); F->read_handler = handler; F->read_data = client_data; } if(type & RB_SELECT_WRITE) { pe_update_events(F, POLLWRNORM, handler); F->write_handler = handler; F->write_data = client_data; } } /* * rb_select * * Called to do the new-style IO, courtesy of squid (like most of this * new IO code). This routine handles the stuff we've hidden in * rb_setselect and fd_table[] and calls callbacks for IO ready * events. */ int rb_select_ports(long delay) { int i, fd; uint nget = 1; struct timespec poll_time; struct timer_data *tdata; poll_time.tv_sec = delay / 1000; poll_time.tv_nsec = (delay % 1000) * 1000000; i = port_getn(pe, pelst, pemax, &nget, &poll_time); rb_set_time(); if (i == -1) return RB_OK; for (i = 0; i < nget; i++) { switch(pelst[i].portev_source) { case PORT_SOURCE_FD: fd = pelst[i].portev_object; PF *hdl = NULL; rb_fde_t *F = rb_find_fd(fd); if ((pelst[i].portev_events & POLLRDNORM) && (hdl = F->read_handler)) { F->read_handler = NULL; hdl(F, F->read_data); } if ((pelst[i].portev_events & POLLWRNORM) && (hdl = F->write_handler)) { F->write_handler = NULL; hdl(F, F->write_data); } break; } } return RB_OK; } #else /* ports not supported */ int rb_init_netio_ports(void) { return ENOSYS; } void rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data) { errno = ENOSYS; return; } int rb_select_ports(long delay) { errno = ENOSYS; return -1; } int rb_setup_fd_ports(rb_fde_t *F) { errno = ENOSYS; return -1; } #endif