ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/lib/poll.c
Revision: 1.3
Committed: Sat Jan 17 01:18:36 2004 UTC (20 years, 8 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +1 -1 lines
State: FILE REMOVED
Log Message:
*** empty log message ***

File Contents

# Content
1 #if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL)
2 /* nothing to do, all is well, gore is president. */
3 #else
4
5 /*---------------------------------------------------------------------------*\
6 $Id: poll.c,v 1.2 2003/10/14 19:14:27 pcg Exp $
7
8 NAME
9
10 poll - select(2)-based poll() emulation function for BSD systems.
11
12 SYNOPSIS
13 #include "poll.h"
14
15 struct pollfd
16 {
17 int fd;
18 short events;
19 short revents;
20 }
21
22 int poll (struct pollfd *pArray, unsigned long n_fds, int timeout)
23
24 DESCRIPTION
25
26 This file, and the accompanying "poll.h", implement the System V
27 poll(2) system call for BSD systems (which typically do not provide
28 poll()). Poll() provides a method for multiplexing input and output
29 on multiple open file descriptors; in traditional BSD systems, that
30 capability is provided by select(). While the semantics of select()
31 differ from those of poll(), poll() can be readily emulated in terms
32 of select() -- which is how this function is implemented.
33
34 REFERENCES
35 Stevens, W. Richard. Unix Network Programming. Prentice-Hall, 1990.
36
37 NOTES
38 1. This software requires an ANSI C compiler.
39
40 LICENSE
41
42 This software is released under the following license:
43
44 Copyright (c) 1995-2002 Brian M. Clapper
45 All rights reserved.
46
47 Redistribution and use in source and binary forms are
48 permitted provided that: (1) source distributions retain
49 this entire copyright notice and comment; (2) modifications
50 made to the software are prominently mentioned, and a copy
51 of the original software (or a pointer to its location) are
52 included; and (3) distributions including binaries display
53 the following acknowledgement: "This product includes
54 software developed by Brian M. Clapper <bmc@clapper.org>"
55 in the documentation or other materials provided with the
56 distribution. The name of the author may not be used to
57 endorse or promote products derived from this software
58 without specific prior written permission.
59
60 THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS
61 OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
62 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
63 PARTICULAR PURPOSE.
64
65 Effectively, this means you can do what you want with the software
66 except remove this notice or take advantage of the author's name.
67 If you modify the software and redistribute your modified version,
68 you must indicate that your version is a modification of the
69 original, and you must provide either a pointer to or a copy of the
70 original.
71 \*---------------------------------------------------------------------------*/
72
73
74 /*---------------------------------------------------------------------------*\
75 Includes
76 \*---------------------------------------------------------------------------*/
77
78 #include <unistd.h> /* standard Unix definitions */
79 #include <sys/types.h> /* system types */
80 #include <sys/time.h> /* time definitions */
81 #include <assert.h> /* assertion macros */
82 #include <string.h> /* string functions */
83 #include "poll.h" /* this package */
84
85 /*---------------------------------------------------------------------------*\
86 Macros
87 \*---------------------------------------------------------------------------*/
88
89 #ifndef MAX
90 #define MAX(a,b) ((a) > (b) ? (a) : (b))
91 #endif
92
93
94 /*---------------------------------------------------------------------------*\
95 Private Functions
96 \*---------------------------------------------------------------------------*/
97
98 static int map_poll_spec
99 #if __STDC__ > 0
100 (struct pollfd *pArray,
101 unsigned long n_fds,
102 fd_set *pReadSet,
103 fd_set *pWriteSet,
104 fd_set *pExceptSet)
105 #else
106 (pArray, n_fds, pReadSet, pWriteSet, pExceptSet)
107 struct pollfd *pArray;
108 unsigned long n_fds;
109 fd_set *pReadSet;
110 fd_set *pWriteSet;
111 fd_set *pExceptSet;
112 #endif
113 {
114 register unsigned long i; /* loop control */
115 register struct pollfd *pCur; /* current array element */
116 register int max_fd = -1; /* return value */
117
118 /*
119 Map the poll() structures into the file descriptor sets required
120 by select().
121 */
122 for (i = 0, pCur = pArray; i < n_fds; i++, pCur++)
123 {
124 /* Skip any bad FDs in the array. */
125
126 if (pCur->fd < 0)
127 continue;
128
129 if (pCur->events & POLLIN)
130 {
131 /* "Input Ready" notification desired. */
132 FD_SET (pCur->fd, pReadSet);
133 }
134
135 if (pCur->events & POLLOUT)
136 {
137 /* "Output Possible" notification desired. */
138 FD_SET (pCur->fd, pWriteSet);
139 }
140
141 if (pCur->events & POLLPRI)
142 {
143 /*
144 "Exception Occurred" notification desired. (Exceptions
145 include out of band data.
146 */
147 FD_SET (pCur->fd, pExceptSet);
148 }
149
150 max_fd = MAX (max_fd, pCur->fd);
151 }
152
153 return max_fd;
154 }
155
156 static struct timeval *map_timeout
157 #if __STDC__ > 0
158 (int poll_timeout, struct timeval *pSelTimeout)
159 #else
160 (poll_timeout, pSelTimeout)
161 int poll_timeout;
162 struct timeval *pSelTimeout;
163 #endif
164 {
165 struct timeval *pResult;
166
167 /*
168 Map the poll() timeout value into a select() timeout. The possible
169 values of the poll() timeout value, and their meanings, are:
170
171 VALUE MEANING
172
173 -1 wait indefinitely (until signal occurs)
174 0 return immediately, don't block
175 >0 wait specified number of milliseconds
176
177 select() uses a "struct timeval", which specifies the timeout in
178 seconds and microseconds, so the milliseconds value has to be mapped
179 accordingly.
180 */
181
182 assert (pSelTimeout != (struct timeval *) NULL);
183
184 switch (poll_timeout)
185 {
186 case -1:
187 /*
188 A NULL timeout structure tells select() to wait indefinitely.
189 */
190 pResult = (struct timeval *) NULL;
191 break;
192
193 case 0:
194 /*
195 "Return immediately" (test) is specified by all zeros in
196 a timeval structure.
197 */
198 pSelTimeout->tv_sec = 0;
199 pSelTimeout->tv_usec = 0;
200 pResult = pSelTimeout;
201 break;
202
203 default:
204 /* Wait the specified number of milliseconds. */
205 pSelTimeout->tv_sec = poll_timeout / 1000; /* get seconds */
206 poll_timeout %= 1000; /* remove seconds */
207 pSelTimeout->tv_usec = poll_timeout * 1000; /* get microseconds */
208 pResult = pSelTimeout;
209 break;
210 }
211
212
213 return pResult;
214 }
215
216 static void map_select_results
217 #if __STDC__ > 0
218 (struct pollfd *pArray,
219 unsigned long n_fds,
220 fd_set *pReadSet,
221 fd_set *pWriteSet,
222 fd_set *pExceptSet)
223 #else
224 (pArray, n_fds, pReadSet, pWriteSet, pExceptSet)
225 struct pollfd *pArray;
226 unsigned long n_fds;
227 fd_set *pReadSet;
228 fd_set *pWriteSet;
229 fd_set *pExceptSet;
230 #endif
231 {
232 register unsigned long i; /* loop control */
233 register struct pollfd *pCur; /* current array element */
234
235 for (i = 0, pCur = pArray; i < n_fds; i++, pCur++)
236 {
237 /* Skip any bad FDs in the array. */
238
239 if (pCur->fd < 0)
240 continue;
241
242 /* Exception events take priority over input events. */
243
244 pCur->revents = 0;
245 if (FD_ISSET (pCur->fd, pExceptSet))
246 pCur->revents |= POLLPRI;
247
248 else if (FD_ISSET (pCur->fd, pReadSet))
249 pCur->revents |= POLLIN;
250
251 if (FD_ISSET (pCur->fd, pWriteSet))
252 pCur->revents |= POLLOUT;
253 }
254
255 return;
256 }
257
258 /*---------------------------------------------------------------------------*\
259 Public Functions
260 \*---------------------------------------------------------------------------*/
261
262 int poll
263
264 #if __STDC__ > 0
265 (struct pollfd *pArray, unsigned long n_fds, int timeout)
266 #else
267 (pArray, n_fds, timeout)
268 struct pollfd *pArray;
269 unsigned long n_fds;
270 int timeout;
271 #endif
272
273 {
274 fd_set read_descs; /* input file descs */
275 fd_set write_descs; /* output file descs */
276 fd_set except_descs; /* exception descs */
277 struct timeval stime; /* select() timeout value */
278 int ready_descriptors; /* function result */
279 int max_fd; /* maximum fd value */
280 struct timeval *pTimeout; /* actually passed */
281
282 FD_ZERO (&read_descs);
283 FD_ZERO (&write_descs);
284 FD_ZERO (&except_descs);
285
286 assert (pArray != (struct pollfd *) NULL);
287
288 /* Map the poll() file descriptor list in the select() data structures. */
289
290 max_fd = map_poll_spec (pArray, n_fds,
291 &read_descs, &write_descs, &except_descs);
292
293 /* Map the poll() timeout value in the select() timeout structure. */
294
295 pTimeout = map_timeout (timeout, &stime);
296
297 /* Make the select() call. */
298
299 ready_descriptors = select (max_fd + 1, &read_descs, &write_descs,
300 &except_descs, pTimeout);
301
302 if (ready_descriptors >= 0)
303 {
304 map_select_results (pArray, n_fds,
305 &read_descs, &write_descs, &except_descs);
306 }
307
308 return ready_descriptors;
309 }
310
311 #endif
312