poll(), ppoll()
Multiplex input/output over a set of file descriptors
Synopsis:
#include <sys/poll.h>
int poll( struct pollfd *fds,
nfds_t nfds,
int timeout );
int ppoll( struct pollfd fds,
nfds_t nfds,
const struct timespec * restrict timeout,
const sigset_t * restrict newsigmask );
Arguments:
- fds
- An array of pollfd structures that defines the file descriptors and events of interest.
- nfds
- The number of elements in the fds array.
- timeout
- The length of time to wait for an event on the file descriptors.
- For poll(), it's an integer that specifies the timeout in milliseconds. Specify 0 to return immediately (for true polling), or -1 to block until a requested event occurs; see below.
- For ppoll(), it's a pointer to a timespec structure that specifies the timeout in seconds and nanoseconds (for more information, go to timespec). A NULL pointer or a non-NULL pointer to a timespec that specifies a negative time blocks until an event occurs. A non-NULL pointer to a zero-valued timespec structure returns immediately (for true polling).
- newsigmask
- (ppoll() only) NULL, or a pointer to a sigset_t that specifies a signal mask to apply to the calling thread while it blocks to wait for a requested event to occur.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The poll() function provides applications with a mechanism for multiplexing input/output over a set of file descriptors.
struct pollfd {
int fd;
short events;
short revents;
};
The members are:
- fd
- The file descriptor to be examined.
- events
- Flags that indicate the type of events to look for.
- revents
- Returned event flags.
For each member of the array pointed to by fds, poll() examines the given file descriptor for the event(s) specified in events. The number of pollfd structures in the fds array is given by nfds. Within a structure, fd specifies an open file descriptor, and events and revents are bitmasks constructed by ORing a combination of the following event flags:
- POLLERR
- An error has occurred on the device. This flag is valid only in the revents bitmask; it's ignored in the events member.
- POLLHUP
- The device has been disconnected.
This event and POLLOUT are mutually exclusive; a device can never be writable if a hangup has occurred.
However, this event and POLLIN,
POLLRDNORM, POLLRDBAND, or
POLLPRI aren't mutually exclusive.
Note:If the remote end of a socket is closed, poll() indicates both POLLIN and POLLHUP events.
This flag is valid only in the revents bitmask; it's ignored in the events member.
- POLLIN
- Data other than high-priority data may be read without blocking.
This is equivalent to
POLLRDNORM | POLLRDBAND. - POLLNVAL
- The specified fd value is invalid. This flag is valid only in the revents member; it's ignored in the events member.
- POLLOUT
- Normal data may be written without blocking.
- POLLPRI
- High-priority data may be read without blocking.
- POLLRDBAND
- Priority data may be read without blocking.
- POLLRDNORM
- Normal data may be read without blocking.
- POLLWRBAND
- Priority data may be written.
- POLLWRNORM
- Equivalent to POLLOUT.
The significance and semantics of normal, priority, and high-priority data are file- and device-specific.
If the value of fd is less than 0, events is ignored, and revents is set to 0 in that entry on return from poll().
In each pollfd structure, poll() clears the revents member, except that where the application requested a report on a condition by setting one of the bits of events flags listed above, poll() sets the corresponding bit in revents if the requested condition is true. In addition, poll() sets the POLLHUP, POLLERR, and POLLNVAL flag in revents if the condition is true, even if the application didn't set the corresponding bit in events.
If none of the defined events have occurred on any selected file descriptor, poll() waits at least for the length of time specified by timeout for an event to occur on any of the selected file descriptors. If the value of timeout is 0, poll() returns immediately. If the value of timeout is -1, poll() blocks until a requested event occurs or until the call is interrupted.
The ppoll() function is similar to poll(). If newsigmask isn't NULL and the calling thread is blocking to wait for the requested event to occur, ppoll() replaces the caller's signal mask with the set of signals pointed to by newsigmask before examining the descriptors. It restores the caller's signal mask before returning. Calling ppoll() with a newsigmask of NULL has the same behavior as calling poll().
The poll() function isn't affected by the O_NONBLOCK flag.
The poll() function reports regular files, terminal and pseudo-terminal devices, FIFOs, and pipes. Regular files always poll TRUE for reading and writing.
A file descriptor for a socket that's listening for connections indicates that it's ready for reading, once connections are available. A file descriptor for a socket that connects asynchronously indicates that it's ready for writing once a connection has been established.
For more information, see also <sys/poll.h>.
Returns:
- > 0
- The total number of file descriptors that have been selected.
- 0
- The call timed out, and no file descriptor has been selected.
- -1
- An error occurred (errno is set).
Errors:
- EAGAIN
- The allocation of internal data structures failed, but a subsequent request may succeed.
- EINTR
- A signal was caught during poll().
- EFAULT
- The fds argument pointed to a nonexistent portion of the calling process's address space.
- ENOMEM
- There was not enough memory.
Examples:
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/poll.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
struct sockaddr_in sad;
void *
client(void *arg)
{
int s;
const char *p = "Some data\n";
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return NULL;
}
if (connect(s, (struct sockaddr *)&sad, sizeof(sad)) == -1) {
perror("connect");
return NULL;
}
write(s, p, strlen(p));
close(s);
return NULL;
}
int
main(void)
{
struct pollfd fds;
int s = -1, s2 = -1, done_accept = 0, oflags, ret;
char buf[100];
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return 1;
}
sad.sin_family = AF_INET;
sad.sin_len = sizeof(sad);
sad.sin_addr.s_addr = inet_addr("127.0.0.1");
sad.sin_port = htons(1234);
fds.fd = s;
fds.events = POLLRDNORM;
oflags = fcntl(s, F_GETFL);
oflags |= O_NONBLOCK;
fcntl(s, F_SETFL, oflags);
if (bind(s, (struct sockaddr *)&sad, sizeof(sad)) == -1) {
perror("bind");
return 1;
}
listen(s, 5);
if ((ret = pthread_create(NULL, NULL, client, NULL)) != EOK) {
fprintf(stderr, "pthread_create: %s\n", strerror(ret));
return 1;
}
for (;;) {
if ((ret = poll(&fds, 1, -1)) == -1) {
perror("poll");
break;
}
else if (ret != 1 || (fds.revents & POLLRDNORM) == 0) {
break;
}
if (done_accept) {
if ((ret = read(s2, buf, sizeof(buf))) <= 0) {
break;
}
printf("%s", buf);
}
else {
if ((s2 = accept(s, NULL, 0)) == -1) {
perror("accept");
break;
}
fds.fd = s2;
done_accept = 1;
}
}
close(s);
close(s2);
return 0;
}
Classification:
| Safety: | |
|---|---|
| Cancellation point | Yes |
| Signal handler | No |
| Thread | Yes |
Caveats:
Not all managers support POLLPRI, POLLWRBAND, POLLERR, and POLLHUP.
