1 POLL(7D) Devices POLL(7D)
2
3
4
5 NAME
6 poll - driver for fast poll on many file descriptors
7
8 SYNOPSIS
9 #include <sys/devpoll.h>
10 int fd = open("/dev/poll", O_RDWR);
11 ssize_t n = write(int fd, struct pollfd buf[], int bufsize);
12 int n = ioctl(int fd, DP_POLL, struct dvpoll* arg);
13 int n = ioctl(int fd, DP_ISPOLLED, struct pollfd* pfd);
14
15
16 PARAMETERS
17 fd
18 Open file descriptor that refers to the /dev/poll driver.
19
20
21 path
22 /dev/poll
23
24
25 buf
26 Array of pollfd structures.
27
28
29 bufsize
30 Size of buf in bytes.
31
32
33 arg
34 Pointer to pollcall structure.
35
36
37 pfd
38 Pointer to pollfd structure.
39
40
41 DESCRIPTION
42 The /dev/poll driver is a special driver that enables you to monitor
43 multiple sets of polled file descriptors. By using the /dev/poll
44 driver, you can efficiently poll large numbers of file descriptors.
45 Access to the /dev/poll driver is provided through open(2), write(2),
46 and ioctl(2) system calls.
47
48
49 Writing an array of pollfd struct to the /dev/poll driver has the
50 effect of adding these file descriptors to the monitored poll file
51 descriptor set represented by the fd. To monitor multiple file
52 descriptor sets, open the /dev/poll driver multiple times. Each fd
53 corresponds to one set. For each pollfd struct entry (defined in
54 sys/poll.h):
55
56 struct pollfd {
57 int fd;
58 short events;
59 short revents;
60 }
61
62
63
64 The fd field specifies the file descriptor being polled. The events
65 field indicates the interested poll events on the file descriptor. If a
66 pollfd array contains multiple pollfd entries with the same fd field,
67 the "events" field in each pollfd entry is OR'ed. A special POLLREMOVE
68 event in the events field of the pollfd structure removes the fd from
69 the monitored set. The revents field is not used. Write returns the
70 number of bytes written successfully or -1 when write fails.
71
72
73 The DP_POLL ioctl is used to retrieve returned poll events occurred on
74 the polled file descriptors in the monitored set represented by fd.
75 arg is a pointer to the devpoll structures which are defined as
76 follows:
77
78 struct dvpoll {
79 struct pollfd* dp_fds;
80 int dp_nfds;
81 int dp_timeout;
82 }
83
84
85
86 The dp_fds points to a buffer that holds an array of returned pollfd
87 structures. The dp_nfds field specifies the size of the buffer in terms
88 of the number of pollfd entries it contains. The dp_nfds field also
89 indicates the maximum number of file descriptors from which poll
90 information can be obtained. If there is no interested events on any
91 of the polled file descriptors, the DP_POLL ioctl call will wait
92 dp_timeout milliseconds before returning. If dp_timeout is 0, the ioctl
93 call returns immediately. If dp_timeout is -1, the call blocks until an
94 interested poll events is available or the call is interrupted. Upon
95 return, if the ioctl call has failed, -1 is returned. The memory
96 content pointed by dp_fds is not modified. A return value 0 means the
97 ioctl is timed out. In this case, the memory content pointed by dp_fds
98 is not modified. If the call is successful, it returns the number of
99 valid pollfd entries in the array pointed by dp_fds; the contents of
100 the rest of the buffer is undefined. For each valid pollfd entry, the
101 fd field indicates the file descriptor on which the polled events
102 happened. The events field is the user specified poll events. The
103 revents field contains the events occurred. -1 is returned if the
104 call fails.
105
106
107 DP_ISPOLLED ioctl allows you to query if a file descriptor is already
108 in the monitored set represented by fd. The fd field of the pollfd
109 structure indicates the file descriptor of interest. The DP_ISPOLLED
110 ioctl returns 1 if the file descriptor is in the set. The events
111 field contains 0. The revents field contains the currently polled
112 events. The ioctl returns 0 if the file descriptor is not in the set.
113 The pollfd structure pointed by pfd is not modified. The ioctl
114 returns a -1 if the call fails.
115
116 EXAMPLES
117 The following example shows how /dev/poll may be used.
118
119 {
120 ...
121 /*
122 * open the driver
123 */
124 if ((wfd = open("/dev/poll", O_RDWR)) < 0) {
125 exit(-1);
126 }
127 pollfd = (struct pollfd* )malloc(sizeof(struct pollfd) * MAXBUF);
128 if (pollfd == NULL) {
129 close(wfd);
130 exit(-1);
131 }
132 /*
133 * initialize buffer
134 */
135 for (i = 0; i < MAXBUF; i++) {
136 pollfd[i].fd = fds[i];
137 pollfd[i].events = POLLIN;
138 pollfd[i].revents = 0;
139 }
140 if (write(wfd, &pollfd[0], sizeof(struct pollfd) * MAXBUF) !=
141 sizeof(struct pollfd) * MAXBUF) {
142 perror("failed to write all pollfds");
143 close (wfd);
144 free(pollfd);
145 exit(-1);
146 }
147 /*
148 * read from the devpoll driver
149 */
150 dopoll.dp_timeout = -1;
151 dopoll.dp_nfds = MAXBUF;
152 dopoll.dp_fds = pollfd;
153 result = ioctl(wfd, DP_POLL, &dopoll);
154 if (result < 0) {
155 perror("/dev/poll ioctl DP_POLL failed");
156 close (wfd);
157 free(pollfd);
158 exit(-1);
159 }
160 for (i = 0; i < result; i++) {
161 read(dopoll.dp_fds[i].fd, rbuf, STRLEN);
162 }
163 ...
164 }
165
166
167
168 The following example is part of a test program which shows how
169 DP_ISPOLLED() ioctl may be used.
170
171 {
172 ...
173
174 loopcnt = 0;
175 while (loopcnt < ITERATION) {
176 rn = random();
177 rn %= RANGE;
178 if (write(fds[rn], TESTSTRING, strlen(TESTSTRING)) !=
179 strlen(TESTSTRING)) {
180 perror("write to fifo failed.");
181 close (wfd);
182 free(pollfd);
183 error = 1;
184 goto out1;
185 }
186 dpfd.fd = fds[rn];
187 dpfd.events = 0;
188 dpfd.revents = 0;
189 result = ioctl(wfd, DP_ISPOLLED, &dpfd);
190 if (result < 0) {
191 perror("/dev/poll ioctl DP_ISPOLLED failed");
192 printf("errno = %d\n", errno);
193 close (wfd);
194 free(pollfd);
195 error = 1;
196 goto out1;
197 }
198 if (result != 1) {
199 printf("DP_ISPOLLED returned incorrect result: %d.\n",
200 result);
201 close (wfd);
202 free(pollfd);
203 error = 1;
204 goto out1;
205 }
206 if (dpfd.fd != fds[rn]) {
207 printf("DP_ISPOLLED returned wrong fd %d, expect %d\n",
208 dpfd.fd, fds[rn]);
209 close (wfd);
210 free(pollfd);
211 error = 1;
212 goto out1;
213 }
214 if (dpfd.revents != POLLIN) {
215 printf("DP_ISPOLLED returned unexpected revents %d\n",
216 dpfd.revents);
217 close (wfd);
218 free(pollfd);
219 error = 1;
220 goto out1;
221 }
222 if (read(dpfd.fd, rbuf, strlen(TESTSTRING)) !=
223 strlen(TESTSTRING)) {
224 perror("read from fifo failed");
225 close (wfd);
226 free(pollfd);
227 error = 1;
228 goto out1;
229 }
230 loopcnt++;
231 }
232
233
234
235 ERRORS
236 EACCES
237 A process does not have permission to access the content
238 cached in /dev/poll.
239
240
241 EINTR
242 A signal was caught during the execution of the ioctl(2)
243 function.
244
245
246 EFAULT
247 The request argument requires a data transfer to or from a
248 buffer pointed to by arg, but arg points to an illegal
249 address.
250
251
252 EINVAL
253 The request or arg parameter is not valid for this device,
254 or field of the dvpoll struct pointed by arg is not valid
255 (for example, when using write/pwrite dp_nfds is greater
256 than {OPEN_MAX}, or when using the DPPOLL ioctl dp_nfds is
257 greater than or equal to {OPEN_MAX}}.
258
259
260 ENXIO
261 The O_NONBLOCK flag is set, the named file is a FIFO, the
262 O_WRONLY flag is set, and no process has the file open for
263 reading; or the named file is a character special or block
264 special file and the device associated with this special
265 file does not exist.
266
267
268 ATTRIBUTES
269 See attributes(5) for a description of the following attributes:
270
271
272
273
274 +--------------------------------------+
275 |ATTRIBUTE TYPE ATTRIBUTE VALUE |
276 |Architecture SPARC, x86 |
277 |Interface Stability Obsolete |
278 |MT-Level Safe |
279 +--------------------------------------+
280
281 SEE ALSO
282 open(2), poll(2), write(2), attributes(5)
283
284 NOTES
285 The /dev/poll API is particularly beneficial to applications that poll
286 a large number of file descriptors repeatedly. Applications will
287 exhibit the best performance gain if the polled file descriptor list
288 rarely change.
289
290
291 When using the /dev/poll driver, you should remove a closed file
292 descriptor from a monitored poll set. Failure to do so may result in a
293 POLLNVAL revents being returned for the closed file descriptor. When a
294 file descriptor is closed but not removed from the monitored set, and
295 is reused in subsequent open of a different device, you will be polling
296 the device associated with the reused file descriptor. In a
297 multithreaded application, careful coordination among threads doing
298 close and DP_POLL ioctl is recommended for consistent results.
299
300
301 The /dev/poll driver caches a list of polled file descriptors, which
302 are specific to a process. Therefore, the /dev/poll file descriptor of
303 a process will be inherited by its child process, just like any other
304 file descriptors. But the child process will have very limited access
305 through this inherited /dev/poll file descriptor. Any attempt to write
306 or do ioctl by the child process will result in an EACCES error. The
307 child process should close the inherited /dev/poll file descriptor and
308 open its own if desired.
309
310
311 The /dev/poll driver does not yet support polling. Polling on a
312 /dev/poll file descriptor will result in POLLERR being returned in the
313 revents field of pollfd structure.
314
315
316
317 January 10, 2020 POLL(7D)