4
// Warning: a call to this poll() takes about 4K of stack space.
6
// Greg Parker gparker-web@sealiesoftware.com December 2000
7
// This code is in the public domain and may be copied or modified without
11
// * fix crash when an fd is less than 0
12
// * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE
13
// * don't set POLLIN or POLLOUT in revents if it wasn't requested
14
// in events (only happens when an fd is in the poll set twice)
20
#include <sys/types.h>
26
typedef struct pollfd {
27
int fd; /* file desc to poll */
28
short events; /* events of interest on fd */
29
short revents; /* events that occurred on fd */
35
#define POLLOUT 0x0004
36
#define POLLERR 0x0008
39
#define POLLNORM POLLIN
40
#define POLLPRI POLLIN
41
#define POLLRDNORM POLLIN
42
#define POLLRDBAND POLLIN
43
#define POLLWRNORM POLLOUT
44
#define POLLWRBAND POLLOUT
47
#define POLLHUP 0x0010
48
#define POLLNVAL 0x0020
51
poll(struct pollfd *pollSet, int pollCount, int pollTimeout)
55
fd_set readFDs, writeFDs, exceptFDs;
56
fd_set *readp, *writep, *exceptp;
57
struct pollfd *pollEnd, *p;
70
pollEnd = pollSet + pollCount;
79
// Find the biggest fd in the poll set
81
for (p = pollSet; p < pollEnd; p++) {
82
if (p->fd > maxFD) maxFD = p->fd;
85
if (maxFD >= FD_SETSIZE) {
86
// At least one fd is too big
91
// Transcribe flags from the poll set to the fd sets
92
for (p = pollSet; p < pollEnd; p++) {
94
// Negative fd checks nothing and always reports zero
96
if (p->events & POLLIN) FD_SET(p->fd, readp);
97
if (p->events & POLLOUT) FD_SET(p->fd, writep);
99
FD_SET(p->fd, exceptp);
101
// POLLERR is never set coming in; poll() always reports errors
102
// But don't report if we're not listening to anything at all.
107
// poll timeout is in milliseconds. Convert to struct timeval.
108
// poll timeout == -1 : wait forever : select timeout of NULL
109
// poll timeout == 0 : return immediately : select timeout of zero
110
if (pollTimeout >= 0) {
111
tv.tv_sec = pollTimeout / 1000;
112
tv.tv_usec = (pollTimeout % 1000) * 1000;
118
selected = select(maxFD+1, readp, writep, exceptp, tvp);
121
// Error during select
124
else if (selected > 0) {
125
// Select found something
126
// Transcribe result from fd sets to poll set.
127
// Also count the number of selected fds. poll returns the
128
// number of ready fds; select returns the number of bits set.
130
for (p = pollSet; p < pollEnd; p++) {
133
// Negative fd always reports zero
135
if ((p->events & POLLIN) && FD_ISSET(p->fd, readp)) {
136
p->revents |= POLLIN;
138
if ((p->events & POLLOUT) && FD_ISSET(p->fd, writep)) {
139
p->revents |= POLLOUT;
141
if ((p->events != 0) && FD_ISSET(p->fd, exceptp)) {
142
p->revents |= POLLERR;
145
if (p->revents) polled++;
151
// selected == 0, select timed out before anything happened
152
// Clear all result bits and return zero.
153
for (p = pollSet; p < pollEnd; p++) {