1 /* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 /* Wrapper for poll(). Allocates and extends array of struct pollfds,
20 keeps them in fd order so that we can set and test conditions on
21 fd using a simple but efficient binary chop. */
24 poll_listen(fd, event)
27 poll_listen(fd, event);
29 hits = do_poll(timeout);
31 if (poll_check(fd, event)
35 if (poll_check(fd, event)
39 event is OR of POLLIN, POLLOUT, POLLERR, etc
42 static struct pollfd *pollfds = NULL;
43 static nfds_t nfds, arrsize = 0;
45 /* Binary search. Returns either the pollfd with fd, or
46 if the fd doesn't match, or return equals nfds, the entry
47 to the left of which a new record should be inserted. */
48 static nfds_t fd_search(int fd)
50 nfds_t left, right, mid;
52 if ((right = nfds) == 0)
59 if (right == left + 1)
60 return (pollfds[left].fd >= fd) ? left : right;
62 mid = (left + right)/2;
64 if (pollfds[mid].fd > fd)
76 int do_poll(int timeout)
78 return poll(pollfds, nfds, timeout);
81 int poll_check(int fd, short event)
83 nfds_t i = fd_search(fd);
85 if (i < nfds && pollfds[i].fd == fd)
86 return pollfds[i].revents & event;
91 void poll_listen(int fd, short event)
93 nfds_t i = fd_search(fd);
95 if (i < nfds && pollfds[i].fd == fd)
96 pollfds[i].events |= event;
101 /* Array too small, extend. */
104 arrsize = (arrsize == 0) ? 64 : arrsize * 2;
106 if (!(new = whine_realloc(pollfds, arrsize * sizeof(struct pollfd))))
112 memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
115 pollfds[i].events = event;