3 // Warning: a call to this poll() takes about 4K of stack space.
5 // Greg Parker gparker-web@sealiesoftware.com December 2000
6 // This code is in the public domain and may be copied or modified without
10 // * fix crash when an fd is less than 0
11 // * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE
12 // * don't set POLLIN or POLLOUT in revents if it wasn't requested
13 // in events (only happens when an fd is in the poll set twice)
19 #define FD_SETSIZE OPEN_MAX
20 #include <sys/types.h>
25 typedef struct pollfd
{
26 int fd
; /* file desc to poll */
27 short events
; /* events of interest on fd */
28 short revents
; /* events that occurred on fd */
34 #define POLLOUT 0x0004
35 #define POLLERR 0x0008
38 #define POLLNORM POLLIN
39 #define POLLPRI POLLIN
40 #define POLLRDNORM POLLIN
41 #define POLLRDBAND POLLIN
42 #define POLLWRNORM POLLOUT
43 #define POLLWRBAND POLLOUT
46 #define POLLHUP 0x0010
47 #define POLLNVAL 0x0020
50 inline int poll(struct pollfd
*pollSet
, int pollCount
, int pollTimeout
)
54 fd_set readFDs
, writeFDs
, exceptFDs
;
55 fd_set
*readp
, *writep
, *exceptp
;
56 struct pollfd
*pollEnd
, *p
;
69 pollEnd
= pollSet
+ pollCount
;
78 // Find the biggest fd in the poll set
80 for (p
= pollSet
; p
< pollEnd
; p
++) {
81 if (p
->fd
> maxFD
) maxFD
= p
->fd
;
84 if (maxFD
>= FD_SETSIZE
) {
85 // At least one fd is too big
90 // Transcribe flags from the poll set to the fd sets
91 for (p
= pollSet
; p
< pollEnd
; p
++) {
93 // Negative fd checks nothing and always reports zero
95 if (p
->events
& POLLIN
) FD_SET(p
->fd
, readp
);
96 if (p
->events
& POLLOUT
) FD_SET(p
->fd
, writep
);
97 if (p
->events
!= 0) FD_SET(p
->fd
, exceptp
);
98 // POLLERR is never set coming in; poll() always reports errors
99 // But don't report if we're not listening to anything at all.
104 // poll timeout is in milliseconds. Convert to struct timeval.
105 // poll timeout == -1 : wait forever : select timeout of NULL
106 // poll timeout == 0 : return immediately : select timeout of zero
107 if (pollTimeout
>= 0) {
108 tv
.tv_sec
= pollTimeout
/ 1000;
109 tv
.tv_usec
= (pollTimeout
% 1000) * 1000;
116 selected
= select(maxFD
+1, readp
, writep
, exceptp
, tvp
);
120 // Error during select
123 else if (selected
> 0) {
124 // Select found something
125 // Transcribe result from fd sets to poll set.
126 // Also count the number of selected fds. poll returns the
127 // number of ready fds; select returns the number of bits set.
129 for (p
= pollSet
; p
< pollEnd
; p
++) {
132 // Negative fd always reports zero
134 if ((p
->events
& POLLIN
) && FD_ISSET(p
->fd
, readp
)) {
135 p
->revents
|= POLLIN
;
137 if ((p
->events
& POLLOUT
) && FD_ISSET(p
->fd
, writep
)) {
138 p
->revents
|= POLLOUT
;
140 if ((p
->events
!= 0) && FD_ISSET(p
->fd
, exceptp
)) {
141 p
->revents
|= POLLERR
;
144 if (p
->revents
) polled
++;
150 // selected == 0, select timed out before anything happened
151 // Clear all result bits and return zero.
152 for (p
= pollSet
; p
< pollEnd
; p
++) {