poll(7d)
NAME
poll - driver for fast poll on many file descriptors
SYNOPSIS
#include <sys/devpoll.h>
int fd = open("/dev/poll", O_RDWR);
ssize_t n = write(int fd, struct pollfd buf[], int bufsize);
int n = ioctl(int fd, DP_POLL, struct dvpoll* arg);
int n = ioctl(int fd, DP_ISPOLLED, struct pollfd* pfd);
PARAMETERS
fd Open file descriptor that refers to the /dev/poll
driver.
path /dev/poll
buf Array of pollfd structures.
bufsize
Size of buf in bytes.
arg Pointer to pollcall structure.
pfd Pointer to pollfd structure.
DESCRIPTION
The /dev/poll driver is a special driver that enables you
to monitor multiple sets of polled file descriptors. By
using the /dev/poll driver, you can efficiently poll large
numbers of file descriptors. Access to the /dev/poll driver
is provided through open(2), write(2), and ioctl(2) sys-
tem calls.
Writing an array of pollfd struct to the /dev/poll driver
has the effect of adding these file descriptors to the mon-
itored poll file descriptor set represented by the fd. To
monitor multiple file descriptor sets, open the /dev/poll
driver multiple times. Each fd corresponds to one set. For
each pollfd struct entry (defined in sys/poll.h):
struct pollfd {
int fd;
short events;
short revents;
}
The fd field specifies the file descriptor being polled.
The events field indicates the interested poll events on
the file descriptor. If a pollfd array contains multiple
pollfd entries with the same fd field, the "events" field in
each pollfd entry is OR'ed. A special POLLREMOVE event in
the events field of the pollfd structure removes the fd
from the monitored set. The revents field is not used. Write
returns the number of bytes written successfully or -1 when
write fails.
The DP_POLL ioctl is used to retrieve returned poll events
occured on the polled file descriptors in the monitored set
represented by fd. arg is a pointer to the devpoll struc-
tures which are defined as follows:
struct dvpoll {
struct pollfd* dp_fds;
int dp_nfds;
int dp_timeout;
}
The dp_fds points to a buffer that holds an array of
returned pollfd structures. The dp_nfds field specifies the
size of the buffer in terms of the number of pollfd entries
it contains. The dp_nfds field also indicates the maximum
number of file descriptors from which poll information can
be obtained. If there is no interested events on any of the
polled file descriptors, the DP_POLL ioctl call will wait
dp_timeout milliseconds before returning. If dp_timeout is
0, the ioctl call returns immediately. If dp_timeout is -1,
the call blocks until an interested poll events is available
or the call is interrupted. Upon return, if the ioctl call
has failed, -1 is returned. The memory content pointed by
dp_fds is not modified. A return value 0 means the ioctl is
timed out. In this case, the memory content pointed by
dp_fds is not modified. If the call is successful, it
returns the number of valid pollfd entries in the array
pointed by dp_fds; the contents of the rest of the buffer
is undefined. For each valid pollfd entry, the fd field
indicates the file desciptor on which the polled events
happened. The events field is the user specified poll
events. The revents field contains the events occurred. -1
is returned if the call fails.
DP_ISPOLLED ioctl allows you to query if a file descriptor
is already in the monitored set represented by fd. The fd
field of the pollfd structure indicates the file descriptor
of interest. The DP_ISPOLLED ioctl returns 1 if the file
descriptor is in the set. The events field contains the
currently polled events. The revents field contains 0.
The ioctl returns 0 if the file descriptor is not in the
set. The pollfd structure pointed by pfd is not modified.
The ioctl returns a -1 if the call fails.
EXAMPLES
The following example shows how /dev/poll may be used.
{
...
/*
* open the driver
*/
if ((wfd = open("/dev/poll", O_RDWR)) < 0) {
exit(-1);
}
pollfd = (struct pollfd* )malloc(sizeof(struct pollfd) * MAXBUF);
if (pollfd == NULL) {
close(wfd);
exit(-1);
}
/*
* initialize buffer
*/
for (i = 0; i < MAXBUF; i++) {
pollfd[i].fd = fds[i];
pollfd[i].events = POLLIN;
pollfd[i].revents = 0;
}
if (write(wfd, &pollfd[0], sizeof(struct pollfd) * MAXBUF) !=
sizeof(struct pollfd) * MAXBUF) {
perror("failed to write all pollfds");
close (wfd);
free(pollfd);
exit(-1);
}
/*
* read from the devpoll driver
*/
dopoll.dp_timeout = -1;
dopoll.dp_nfds = MAXBUF;
dopoll.dp_fds = pollfd;
result = ioctl(wfd, DP_POLL, &dopoll);
if (result < 0) {
perror("/dev/poll ioctl DP_POLL failed");
close (wfd);
free(pollfd);
exit(-1);
}
for (i = 0; i < result; i++) {
read(dopoll.dp_fds[i].fd, rbuf, STRLEN);
}
...
}
The following example is part of a test program which shows
how DP_ISPOLLED() ioctl may be used.
{
...
loopcnt = 0;
while (loopcnt < ITERATION) {
rn = random();
rn %= RANGE;
if (write(fds[rn], TESTSTRING, strlen(TESTSTRING)) !=
strlen(TESTSTRING)) {
perror("write to fifo failed.");
close (wfd);
free(pollfd);
error = 1;
goto out1;
}
dpfd.fd = fds[rn];
dpfd.events = 0;
dpfd.revents = 0;
result = ioctl(wfd, DP_ISPOLLED, &dpfd);
if (result < 0) {
perror("/dev/poll ioctl DP_ISPOLLED failed");
printf("errno = %d\n", errno);
close (wfd);
free(pollfd);
error = 1;
goto out1;
}
if (result != 1) {
printf("DP_ISPOLLED returned incorrect result: %d.\n",
result);
close (wfd);
free(pollfd);
error = 1;
goto out1;
}
if (dpfd.fd != fds[rn]) {
printf("DP_ISPOLLED returned wrong fd %d, expect %d\n",
dpfd.fd, fds[rn]);
close (wfd);
free(pollfd);
error = 1;
goto out1;
}
if (dpfd.revents != POLLIN) {
printf("DP_ISPOLLED returned unexpected revents %d\n",
dpfd.revents);
close (wfd);
free(pollfd);
error = 1;
goto out1;
}
if (read(dpfd.fd, rbuf, strlen(TESTSTRING)) !=
strlen(TESTSTRING)) {
perror("read from fifo failed");
close (wfd);
free(pollfd);
error = 1;
goto out1;
}
loopcnt++;
}
ERRORS
EACCES
A process does not have permission to access the con-
tent cached in /dev/poll.
EINTR A signal was caught during the execution of the
ioctl(2) function.
EFAULT
The request argument requires a data transfer to or
from a buffer pointed to by arg, but arg points to an
illegal address.
EINVAL
The request or arg parameter is not valid for this
device.
ENXIO The O_NONBLOCK flag is set, the named file is a FIFO,
the O_WRONLY flag is set, and no process has the file
open for reading; or the named file is a character
special or block special file and the device associ-
ated with this special file does not exist.
ATTRIBUTES
See attributes(5) for a description of the following attri-
butes:
____________________________________________________________
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
| Architecture | SPARC, x86 |
| Availability | SUNWcarx.u, SUNWcsxu (64|
| | bit Solaris) |
| | SUNWcsr, SUNWcsu (32-bit|
| | Solaris on x86) |
| | SUNWhea (header files) |
| Interface Stability | Evolving |
| MT-Level | Safe |
|_____________________________|_____________________________|
SEE ALSO
open(2), poll(2), write(2), attributes(5)
NOTES
The /dev/poll API is particularly beneficial to applications
that poll a large number of file descriptors repeatedly.
Applications will exhibit the best performance gain if the
polled file descriptor list rarely change.
When using the /dev/poll driver, you should remove a closed
file descriptor from a monitored poll set. Failure to do so
may result in a POLLNVAL revents being returned for the
closed file descriptor. When a file descriptor is closed but
not removed from the monitored set, and is reused in subse-
quent open of a different device, you will be polling the
device associated with the reused file descriptor. In a mul-
tithreaded application, careful coordination among threads
doing close and DP_POLL ioctl is recommended for consistent
results.
The /dev/poll driver caches a list of polled file descrip-
tors, which are specific to a process. Therefore, the
/dev/poll file descriptor of a process will be inherited by
its child process, just like any other file descriptors. But
the child process will have very limited access through this
inherited /dev/poll file descriptor. Any attempt to write
or do ioctl by the child process will result in an EACCES
error. The child process should close the inherited
/dev/poll file descriptor and open its own if desired.
The /dev/poll driver does not yet support polling. Polling
on a /dev/poll file descriptor will result in POLLERR being
returned in the revents field of pollfd structure.
Man(1) output converted with
man2html