11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $Id: bsd-poll.c,v 1.4 2008/08/29 21:32:38 dtucker Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Permission to use, copy, modify, and distribute this software for any 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * purpose with or without fee is hereby granted, provided that the above 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * copyright notice and this permission notice appear in all copies. 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_POLL) 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_SELECT_H 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/select.h> 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h> 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "bsd-poll.h" 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * A minimal implementation of poll(2), built on top of select(2). 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Only supports POLLIN and POLLOUT flags in pfd.events, and POLLIN, POLLOUT 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and POLLERR flags in revents. 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Supports pfd.fd = -1 meaning "unused" although it's not standard. 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpoll(struct pollfd *fds, nfds_t nfds, int timeout) 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nfds_t i; 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int saved_errno, ret, fd, maxfd = 0; 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL; 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t nmemb; 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct timeval tv, *tvp = NULL; 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < nfds; i++) { 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = fds[i].fd; 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd >= FD_SETSIZE) { 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno = EINVAL; 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood maxfd = MAX(maxfd, fd); 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nmemb = howmany(maxfd + 1 , NFDBITS); 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((readfds = calloc(nmemb, sizeof(fd_mask))) == NULL || 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (writefds = calloc(nmemb, sizeof(fd_mask))) == NULL || 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (exceptfds = calloc(nmemb, sizeof(fd_mask))) == NULL) { 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood saved_errno = ENOMEM; 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = -1; 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* populate event bit vectors for the events we're interested in */ 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < nfds; i++) { 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = fds[i].fd; 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd == -1) 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fds[i].events & POLLIN) { 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(fd, readfds); 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(fd, exceptfds); 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fds[i].events & POLLOUT) { 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(fd, writefds); 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(fd, exceptfds); 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* poll timeout is msec, select is timeval (sec + usec) */ 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (timeout >= 0) { 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tv.tv_sec = timeout / 1000; 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tv.tv_usec = (timeout % 1000) * 1000; 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tvp = &tv; 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp); 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood saved_errno = errno; 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* scan through select results and set poll() flags */ 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < nfds; i++) { 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = fds[i].fd; 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fds[i].revents = 0; 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd == -1) 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(fd, readfds)) { 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fds[i].revents |= POLLIN; 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(fd, writefds)) { 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fds[i].revents |= POLLOUT; 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(fd, exceptfds)) { 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fds[i].revents |= POLLERR; 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodout: 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (readfds != NULL) 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free(readfds); 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (writefds != NULL) 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free(writefds); 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (exceptfds != NULL) 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free(exceptfds); 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret == -1) 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno = saved_errno; 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 120