1cce7d346SDag-Erling Smørgrav /* $Id: bsd-poll.c,v 1.4 2008/08/29 21:32:38 dtucker Exp $ */ 2d4af9e69SDag-Erling Smørgrav 3d4af9e69SDag-Erling Smørgrav /* 4d4af9e69SDag-Erling Smørgrav * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). 5d4af9e69SDag-Erling Smørgrav * 6d4af9e69SDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 7d4af9e69SDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 8d4af9e69SDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 9d4af9e69SDag-Erling Smørgrav * 10d4af9e69SDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11d4af9e69SDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12d4af9e69SDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13d4af9e69SDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14d4af9e69SDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15d4af9e69SDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16d4af9e69SDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17d4af9e69SDag-Erling Smørgrav */ 18d4af9e69SDag-Erling Smørgrav 19d4af9e69SDag-Erling Smørgrav #include "includes.h" 20d4af9e69SDag-Erling Smørgrav #if !defined(HAVE_POLL) 21d4af9e69SDag-Erling Smørgrav 22d4af9e69SDag-Erling Smørgrav #ifdef HAVE_SYS_SELECT_H 23d4af9e69SDag-Erling Smørgrav # include <sys/select.h> 24d4af9e69SDag-Erling Smørgrav #endif 25d4af9e69SDag-Erling Smørgrav 26d4af9e69SDag-Erling Smørgrav #include <stdlib.h> 27d4af9e69SDag-Erling Smørgrav #include <errno.h> 28d4af9e69SDag-Erling Smørgrav #include "bsd-poll.h" 29d4af9e69SDag-Erling Smørgrav 30d4af9e69SDag-Erling Smørgrav /* 31d4af9e69SDag-Erling Smørgrav * A minimal implementation of poll(2), built on top of select(2). 32d4af9e69SDag-Erling Smørgrav * 33d4af9e69SDag-Erling Smørgrav * Only supports POLLIN and POLLOUT flags in pfd.events, and POLLIN, POLLOUT 34d4af9e69SDag-Erling Smørgrav * and POLLERR flags in revents. 35d4af9e69SDag-Erling Smørgrav * 36d4af9e69SDag-Erling Smørgrav * Supports pfd.fd = -1 meaning "unused" although it's not standard. 37d4af9e69SDag-Erling Smørgrav */ 38d4af9e69SDag-Erling Smørgrav 39d4af9e69SDag-Erling Smørgrav int 40d4af9e69SDag-Erling Smørgrav poll(struct pollfd *fds, nfds_t nfds, int timeout) 41d4af9e69SDag-Erling Smørgrav { 42d4af9e69SDag-Erling Smørgrav nfds_t i; 43d4af9e69SDag-Erling Smørgrav int saved_errno, ret, fd, maxfd = 0; 44d4af9e69SDag-Erling Smørgrav fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL; 45d4af9e69SDag-Erling Smørgrav size_t nmemb; 46d4af9e69SDag-Erling Smørgrav struct timeval tv, *tvp = NULL; 47d4af9e69SDag-Erling Smørgrav 48d4af9e69SDag-Erling Smørgrav for (i = 0; i < nfds; i++) { 49cce7d346SDag-Erling Smørgrav fd = fds[i].fd; 50d4af9e69SDag-Erling Smørgrav if (fd >= FD_SETSIZE) { 51d4af9e69SDag-Erling Smørgrav errno = EINVAL; 52d4af9e69SDag-Erling Smørgrav return -1; 53d4af9e69SDag-Erling Smørgrav } 54cce7d346SDag-Erling Smørgrav maxfd = MAX(maxfd, fd); 55d4af9e69SDag-Erling Smørgrav } 56d4af9e69SDag-Erling Smørgrav 57d4af9e69SDag-Erling Smørgrav nmemb = howmany(maxfd + 1 , NFDBITS); 58d4af9e69SDag-Erling Smørgrav if ((readfds = calloc(nmemb, sizeof(fd_mask))) == NULL || 59d4af9e69SDag-Erling Smørgrav (writefds = calloc(nmemb, sizeof(fd_mask))) == NULL || 60d4af9e69SDag-Erling Smørgrav (exceptfds = calloc(nmemb, sizeof(fd_mask))) == NULL) { 61d4af9e69SDag-Erling Smørgrav saved_errno = ENOMEM; 62d4af9e69SDag-Erling Smørgrav ret = -1; 63d4af9e69SDag-Erling Smørgrav goto out; 64d4af9e69SDag-Erling Smørgrav } 65d4af9e69SDag-Erling Smørgrav 66d4af9e69SDag-Erling Smørgrav /* populate event bit vectors for the events we're interested in */ 67d4af9e69SDag-Erling Smørgrav for (i = 0; i < nfds; i++) { 68d4af9e69SDag-Erling Smørgrav fd = fds[i].fd; 69d4af9e69SDag-Erling Smørgrav if (fd == -1) 70d4af9e69SDag-Erling Smørgrav continue; 71d4af9e69SDag-Erling Smørgrav if (fds[i].events & POLLIN) { 72d4af9e69SDag-Erling Smørgrav FD_SET(fd, readfds); 73d4af9e69SDag-Erling Smørgrav FD_SET(fd, exceptfds); 74d4af9e69SDag-Erling Smørgrav } 75d4af9e69SDag-Erling Smørgrav if (fds[i].events & POLLOUT) { 76d4af9e69SDag-Erling Smørgrav FD_SET(fd, writefds); 77d4af9e69SDag-Erling Smørgrav FD_SET(fd, exceptfds); 78d4af9e69SDag-Erling Smørgrav } 79d4af9e69SDag-Erling Smørgrav } 80d4af9e69SDag-Erling Smørgrav 81d4af9e69SDag-Erling Smørgrav /* poll timeout is msec, select is timeval (sec + usec) */ 82d4af9e69SDag-Erling Smørgrav if (timeout >= 0) { 83d4af9e69SDag-Erling Smørgrav tv.tv_sec = timeout / 1000; 84d4af9e69SDag-Erling Smørgrav tv.tv_usec = (timeout % 1000) * 1000; 85d4af9e69SDag-Erling Smørgrav tvp = &tv; 86d4af9e69SDag-Erling Smørgrav } 87d4af9e69SDag-Erling Smørgrav 88d4af9e69SDag-Erling Smørgrav ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp); 89d4af9e69SDag-Erling Smørgrav saved_errno = errno; 90d4af9e69SDag-Erling Smørgrav 91d4af9e69SDag-Erling Smørgrav /* scan through select results and set poll() flags */ 92d4af9e69SDag-Erling Smørgrav for (i = 0; i < nfds; i++) { 93d4af9e69SDag-Erling Smørgrav fd = fds[i].fd; 94d4af9e69SDag-Erling Smørgrav fds[i].revents = 0; 95d4af9e69SDag-Erling Smørgrav if (fd == -1) 96d4af9e69SDag-Erling Smørgrav continue; 97d4af9e69SDag-Erling Smørgrav if (FD_ISSET(fd, readfds)) { 98d4af9e69SDag-Erling Smørgrav fds[i].revents |= POLLIN; 99d4af9e69SDag-Erling Smørgrav } 100d4af9e69SDag-Erling Smørgrav if (FD_ISSET(fd, writefds)) { 101d4af9e69SDag-Erling Smørgrav fds[i].revents |= POLLOUT; 102d4af9e69SDag-Erling Smørgrav } 103d4af9e69SDag-Erling Smørgrav if (FD_ISSET(fd, exceptfds)) { 104d4af9e69SDag-Erling Smørgrav fds[i].revents |= POLLERR; 105d4af9e69SDag-Erling Smørgrav } 106d4af9e69SDag-Erling Smørgrav } 107d4af9e69SDag-Erling Smørgrav 108d4af9e69SDag-Erling Smørgrav out: 109d4af9e69SDag-Erling Smørgrav if (readfds != NULL) 110d4af9e69SDag-Erling Smørgrav free(readfds); 111d4af9e69SDag-Erling Smørgrav if (writefds != NULL) 112d4af9e69SDag-Erling Smørgrav free(writefds); 113d4af9e69SDag-Erling Smørgrav if (exceptfds != NULL) 114d4af9e69SDag-Erling Smørgrav free(exceptfds); 115d4af9e69SDag-Erling Smørgrav if (ret == -1) 116d4af9e69SDag-Erling Smørgrav errno = saved_errno; 117d4af9e69SDag-Erling Smørgrav return ret; 118d4af9e69SDag-Erling Smørgrav } 119d4af9e69SDag-Erling Smørgrav #endif 120