Coverage Report

Created: 2025-08-29 06:42

/src/dnsmasq/src/poll.c
Line
Count
Source (jump to first uncovered line)
1
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
2
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.
7
 
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.
12
     
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/>.
15
*/
16
17
#include "dnsmasq.h"
18
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. */
22
23
/* poll_reset()
24
   poll_listen(fd, event)
25
   .
26
   .
27
   poll_listen(fd, event);
28
29
   hits = do_poll(timeout);
30
31
   if (poll_check(fd, event)
32
    .
33
    .
34
35
   if (poll_check(fd, event)
36
    .
37
    .
38
39
    event is OR of POLLIN, POLLOUT, POLLERR, etc
40
*/
41
42
static struct pollfd *pollfds = NULL;
43
static nfds_t nfds, arrsize = 0;
44
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)
49
0
{
50
0
  nfds_t left, right, mid;
51
  
52
0
  if ((right = nfds) == 0)
53
0
    return 0;
54
  
55
0
  left = 0;
56
  
57
0
  while (1)
58
0
    {
59
0
      if (right == left + 1)
60
0
  return (pollfds[left].fd >= fd) ? left : right;
61
      
62
0
      mid = (left + right)/2;
63
      
64
0
      if (pollfds[mid].fd > fd)
65
0
  right = mid;
66
0
      else 
67
0
  left = mid;
68
0
    }
69
0
}
70
71
void poll_reset(void)
72
0
{
73
0
  nfds = 0;
74
0
}
75
76
int do_poll(int timeout)
77
0
{
78
0
  return poll(pollfds, nfds, timeout);
79
0
}
80
81
int poll_check(int fd, short event)
82
0
{
83
0
  nfds_t i = fd_search(fd);
84
  
85
0
  if (i < nfds && pollfds[i].fd == fd)
86
0
    return pollfds[i].revents & event;
87
88
0
  return 0;
89
0
}
90
91
void poll_listen(int fd, short event)
92
0
{
93
0
   nfds_t i = fd_search(fd);
94
  
95
0
   if (i < nfds && pollfds[i].fd == fd)
96
0
     pollfds[i].events |= event;
97
0
   else
98
0
     {
99
0
       if (arrsize == nfds)
100
0
   {
101
     /* Array too small. Extend. */
102
0
     struct pollfd *new;
103
104
0
     arrsize = (arrsize == 0) ? 64 : arrsize * 2;
105
106
0
     if (!(new = whine_realloc(pollfds, arrsize * sizeof(struct pollfd))))
107
0
       return;
108
109
0
     pollfds = new;
110
0
   }
111
112
0
       memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
113
114
0
       pollfds[i].fd = fd;
115
0
       pollfds[i].events = event;
116
0
       nfds++;
117
0
     }
118
0
}