1 |
#include <stdio.h> |
2 |
#include <errno.h> |
3 |
#include <sys/select.h> |
4 |
#include "my_poll.h" |
5 |
|
6 |
int my_poll(struct pollfd *pollfds, int npollfds, int timeout) |
7 |
{ |
8 |
fd_set reads, writes, excepts; |
9 |
int i, n; |
10 |
int highest = -1; |
11 |
int events; |
12 |
|
13 |
FD_ZERO(&reads); FD_ZERO(&writes); FD_ZERO(&excepts); |
14 |
|
15 |
/* Convert pollfds array to fd_set's. */ |
16 |
for (i = 0; i < npollfds; i++) { |
17 |
/* Ignore invalid descriptors. */ |
18 |
n = pollfds[i].fd; |
19 |
if (n < 0) continue; |
20 |
|
21 |
events = pollfds[i].events; |
22 |
if (events & POLLIN) FD_SET(n, &reads); |
23 |
if (events & POLLOUT) FD_SET(n, &writes); |
24 |
FD_SET(n, &excepts); |
25 |
if (n > highest) highest = n; |
26 |
} |
27 |
|
28 |
if (timeout >= 0) { |
29 |
struct timeval tv; |
30 |
tv.tv_sec = (timeout / 1000); |
31 |
timeout -= 1000 * tv.tv_sec; |
32 |
tv.tv_usec = timeout * 1000; |
33 |
events = select(highest+1, &reads, &writes, &excepts, &tv); |
34 |
} |
35 |
else events = select(highest+1, &reads, &writes, &excepts, NULL); |
36 |
|
37 |
if (events < 0) { |
38 |
/* There is a bad descriptor among us... find it! */ |
39 |
char temp[1]; |
40 |
events = 0; |
41 |
for (i = 0; i < npollfds; i++) { |
42 |
if (pollfds[i].fd < 0) continue; |
43 |
errno = 0; |
44 |
n = write(pollfds[i].fd, temp, 0); |
45 |
if (n < 0 && errno != EINVAL) { |
46 |
pollfds[i].revents = POLLNVAL; |
47 |
events++; |
48 |
} |
49 |
else pollfds[i].revents = 0; |
50 |
} |
51 |
} |
52 |
else for (i = 0; i < npollfds; i++) { |
53 |
n = pollfds[i].fd; |
54 |
pollfds[i].revents = 0; |
55 |
if (FD_ISSET(n, &reads)) pollfds[i].revents |= POLLIN; |
56 |
if (FD_ISSET(n, &writes)) pollfds[i].revents |= POLLOUT; |
57 |
if (FD_ISSET(n, &excepts)) pollfds[i].revents |= POLLERR; |
58 |
} |
59 |
|
60 |
return(events); |
61 |
} |