diff options
Diffstat (limited to '')
-rw-r--r-- | man2/poll.2 | 649 |
1 files changed, 649 insertions, 0 deletions
diff --git a/man2/poll.2 b/man2/poll.2 new file mode 100644 index 0000000..2b024d3 --- /dev/null +++ b/man2/poll.2 @@ -0,0 +1,649 @@ +.\" Copyright (C) 2006, 2019 Michael Kerrisk <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.\" Additions from Richard Gooch <rgooch@atnf.CSIRO.AU> and aeb, 971207 +.\" 2006-03-13, mtk, Added ppoll() + various other rewordings +.\" 2006-07-01, mtk, Added POLLRDHUP + various other wording and +.\" formatting changes. +.\" +.TH poll 2 2023-07-08 "Linux man-pages 6.05.01" +.SH NAME +poll, ppoll \- wait for some event on a file descriptor +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include <poll.h> +.PP +.BI "int poll(struct pollfd *" fds ", nfds_t " nfds ", int " timeout ); +.PP +.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" +.B #include <poll.h> +.PP +.BI "int ppoll(struct pollfd *" fds ", nfds_t " nfds , +.BI " const struct timespec *_Nullable " tmo_p , +.BI " const sigset_t *_Nullable " sigmask ); +.fi +.SH DESCRIPTION +.BR poll () +performs a similar task to +.BR select (2): +it waits for one of a set of file descriptors to become ready +to perform I/O. +The Linux-specific +.BR epoll (7) +API performs a similar task, but offers features beyond those found in +.BR poll (). +.PP +The set of file descriptors to be monitored is specified in the +.I fds +argument, which is an array of structures of the following form: +.PP +.in +4n +.EX +struct pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; +.EE +.in +.PP +The caller should specify the number of items in the +.I fds +array in +.IR nfds . +.PP +The field +.I fd +contains a file descriptor for an open file. +If this field is negative, then the corresponding +.I events +field is ignored and the +.I revents +field returns zero. +(This provides an easy way of ignoring a +file descriptor for a single +.BR poll () +call: simply set the +.I fd +field to its bitwise complement.) +.PP +The field +.I events +is an input parameter, a bit mask specifying the events the application +is interested in for the file descriptor +.IR fd . +This field may be specified as zero, +in which case the only events that can be returned in +.I revents +are +.BR POLLHUP , +.BR POLLERR , +and +.B POLLNVAL +(see below). +.PP +The field +.I revents +is an output parameter, filled by the kernel with the events that +actually occurred. +The bits returned in +.I revents +can include any of those specified in +.IR events , +or one of the values +.BR POLLERR , +.BR POLLHUP , +or +.BR POLLNVAL . +(These three bits are meaningless in the +.I events +field, and will be set in the +.I revents +field whenever the corresponding condition is true.) +.PP +If none of the events requested (and no error) has occurred for any +of the file descriptors, then +.BR poll () +blocks until one of the events occurs. +.PP +The +.I timeout +argument specifies the number of milliseconds that +.BR poll () +should block waiting for a file descriptor to become ready. +The call will block until either: +.IP \[bu] 3 +a file descriptor becomes ready; +.IP \[bu] +the call is interrupted by a signal handler; or +.IP \[bu] +the timeout expires. +.PP +Being "ready" means that the requested operation will not block; thus, +.BR poll ()ing +regular files, +block devices, +and other files with no reasonable polling semantic +.I always +returns instantly as ready to read and write. +.PP +Note that the +.I timeout +interval will be rounded up to the system clock granularity, +and kernel scheduling delays mean that the blocking interval +may overrun by a small amount. +Specifying a negative value in +.I timeout +means an infinite timeout. +Specifying a +.I timeout +of zero causes +.BR poll () +to return immediately, even if no file descriptors are ready. +.PP +The bits that may be set/returned in +.I events +and +.I revents +are defined in \fI<poll.h>\fP: +.TP +.B POLLIN +There is data to read. +.TP +.B POLLPRI +There is some exceptional condition on the file descriptor. +Possibilities include: +.RS +.IP \[bu] 3 +There is out-of-band data on a TCP socket (see +.BR tcp (7)). +.IP \[bu] +A pseudoterminal master in packet mode has seen a state change on the slave +(see +.BR ioctl_tty (2)). +.IP \[bu] +A +.I cgroup.events +file has been modified (see +.BR cgroups (7)). +.RE +.TP +.B POLLOUT +Writing is now possible, though a write larger than the available space +in a socket or pipe will still block (unless +.B O_NONBLOCK +is set). +.TP +.BR POLLRDHUP " (since Linux 2.6.17)" +Stream socket peer closed connection, +or shut down writing half of connection. +The +.B _GNU_SOURCE +feature test macro must be defined +(before including +.I any +header files) +in order to obtain this definition. +.TP +.B POLLERR +Error condition (only returned in +.IR revents ; +ignored in +.IR events ). +This bit is also set for a file descriptor referring +to the write end of a pipe when the read end has been closed. +.TP +.B POLLHUP +Hang up (only returned in +.IR revents ; +ignored in +.IR events ). +Note that when reading from a channel such as a pipe or a stream socket, +this event merely indicates that the peer closed its end of the channel. +Subsequent reads from the channel will return 0 (end of file) +only after all outstanding data in the channel has been consumed. +.TP +.B POLLNVAL +Invalid request: +.I fd +not open (only returned in +.IR revents ; +ignored in +.IR events ). +.PP +When compiling with +.B _XOPEN_SOURCE +defined, one also has the following, +which convey no further information beyond the bits listed above: +.TP +.B POLLRDNORM +Equivalent to +.BR POLLIN . +.TP +.B POLLRDBAND +Priority band data can be read (generally unused on Linux). +.\" POLLRDBAND is used in the DECnet protocol. +.TP +.B POLLWRNORM +Equivalent to +.BR POLLOUT . +.TP +.B POLLWRBAND +Priority data may be written. +.PP +Linux also knows about, but does not use +.BR POLLMSG . +.SS ppoll() +The relationship between +.BR poll () +and +.BR ppoll () +is analogous to the relationship between +.BR select (2) +and +.BR pselect (2): +like +.BR pselect (2), +.BR ppoll () +allows an application to safely wait until either a file descriptor +becomes ready or until a signal is caught. +.PP +Other than the difference in the precision of the +.I timeout +argument, the following +.BR ppoll () +call: +.PP +.in +4n +.EX +ready = ppoll(&fds, nfds, tmo_p, &sigmask); +.EE +.in +.PP +is nearly equivalent to +.I atomically +executing the following calls: +.PP +.in +4n +.EX +sigset_t origmask; +int timeout; +\& +timeout = (tmo_p == NULL) ? \-1 : + (tmo_p\->tv_sec * 1000 + tmo_p\->tv_nsec / 1000000); +pthread_sigmask(SIG_SETMASK, &sigmask, &origmask); +ready = poll(&fds, nfds, timeout); +pthread_sigmask(SIG_SETMASK, &origmask, NULL); +.EE +.in +.PP +The above code segment is described as +.I nearly +equivalent because whereas a negative +.I timeout +value for +.BR poll () +is interpreted as an infinite timeout, a negative value expressed in +.I *tmo_p +results in an error from +.BR ppoll (). +.PP +See the description of +.BR pselect (2) +for an explanation of why +.BR ppoll () +is necessary. +.PP +If the +.I sigmask +argument is specified as NULL, then +no signal mask manipulation is performed +(and thus +.BR ppoll () +differs from +.BR poll () +only in the precision of the +.I timeout +argument). +.PP +The +.I tmo_p +argument specifies an upper limit on the amount of time that +.BR ppoll () +will block. +This argument is a pointer to a +.BR timespec (3) +structure. +.PP +If +.I tmo_p +is specified as NULL, then +.BR ppoll () +can block indefinitely. +.SH RETURN VALUE +On success, +.BR poll () +returns a nonnegative value which is the number of elements in the +.I pollfds +whose +.I revents +fields have been set to a nonzero value (indicating an event or an error). +A return value of zero indicates that the system call timed out +before any file descriptors became ready. +.PP +On error, \-1 is returned, and +.I errno +is set to indicate the error. +.SH ERRORS +.TP +.B EFAULT +.I fds +points outside the process's accessible address space. +The array given as argument was not contained in the calling program's +address space. +.TP +.B EINTR +A signal occurred before any requested event; see +.BR signal (7). +.TP +.B EINVAL +The +.I nfds +value exceeds the +.B RLIMIT_NOFILE +value. +.TP +.B EINVAL +.RB ( ppoll ()) +The timeout value expressed in +.I *tmo_p +is invalid (negative). +.TP +.B ENOMEM +Unable to allocate memory for kernel data structures. +.SH VERSIONS +On some other UNIX systems, +.\" Darwin, according to a report by Jeremy Sequoia, relayed by Josh Triplett +.BR poll () +can fail with the error +.B EAGAIN +if the system fails to allocate kernel-internal resources, rather than +.B ENOMEM +as Linux does. +POSIX permits this behavior. +Portable programs may wish to check for +.B EAGAIN +and loop, just as with +.BR EINTR . +.PP +Some implementations define the nonstandard constant +.B INFTIM +with the value \-1 for use as a +.I timeout +for +.BR poll (). +This constant is not provided in glibc. +.SS C library/kernel differences +The Linux +.BR ppoll () +system call modifies its +.I tmo_p +argument. +However, the glibc wrapper function hides this behavior +by using a local variable for the timeout argument that +is passed to the system call. +Thus, the glibc +.BR ppoll () +function does not modify its +.I tmo_p +argument. +.PP +The raw +.BR ppoll () +system call has a fifth argument, +.IR "size_t sigsetsize" , +which specifies the size in bytes of the +.I sigmask +argument. +The glibc +.BR ppoll () +wrapper function specifies this argument as a fixed value +(equal to +.IR sizeof(kernel_sigset_t) ). +See +.BR sigprocmask (2) +for a discussion on the differences between the kernel and the libc +notion of the sigset. +.SH STANDARDS +.TP +.BR poll () +POSIX.1-2008. +.TP +.BR ppoll () +Linux. +.\" FIXME . +.\" ppoll() is proposed for inclusion in POSIX: +.\" https://www.austingroupbugs.net/view.php?id=1263 +.\" NetBSD 3.0 has a pollts() which is like Linux ppoll(). +.SH HISTORY +.TP +.BR poll () +POSIX.1-2001. +Linux 2.1.23. +.IP +On older kernels that lack this system call, +the glibc +.BR poll () +wrapper function provides emulation using +.BR select (2). +.TP +.BR ppoll () +Linux 2.6.16, +glibc 2.4. +.SH NOTES +The operation of +.BR poll () +and +.BR ppoll () +is not affected by the +.B O_NONBLOCK +flag. +.PP +For a discussion of what may happen if a file descriptor being monitored by +.BR poll () +is closed in another thread, see +.BR select (2). +.SH BUGS +See the discussion of spurious readiness notifications under the +BUGS section of +.BR select (2). +.SH EXAMPLES +The program below opens each of the files named in its command-line +arguments and monitors the resulting file descriptors for readiness to read +.RB ( POLLIN ). +The program loops, repeatedly using +.BR poll () +to monitor the file descriptors, +printing the number of ready file descriptors on return. +For each ready file descriptor, the program: +.IP \[bu] 3 +displays the returned +.I revents +field in a human-readable form; +.IP \[bu] +if the file descriptor is readable, reads some data from it, +and displays that data on standard output; and +.IP \[bu] +if the file descriptor was not readable, +but some other event occurred (presumably +.BR POLLHUP ), +closes the file descriptor. +.PP +Suppose we run the program in one terminal, asking it to open a FIFO: +.PP +.in +4n +.EX +$ \fBmkfifo myfifo\fP +$ \fB./poll_input myfifo\fP +.EE +.in +.PP +In a second terminal window, we then open the FIFO for writing, +write some data to it, and close the FIFO: +.PP +.in +4n +.EX +$ \fBecho aaaaabbbbbccccc > myfifo\fP +.EE +.in +.PP +In the terminal where we are running the program, we would then see: +.PP +.in +4n +.EX +Opened "myfifo" on fd 3 +About to poll() +Ready: 1 + fd=3; events: POLLIN POLLHUP + read 10 bytes: aaaaabbbbb +About to poll() +Ready: 1 + fd=3; events: POLLIN POLLHUP + read 6 bytes: ccccc +\& +About to poll() +Ready: 1 + fd=3; events: POLLHUP + closing fd 3 +All file descriptors closed; bye +.EE +.in +.PP +In the above output, we see that +.BR poll () +returned three times: +.IP \[bu] 3 +On the first return, the bits returned in the +.I revents +field were +.BR POLLIN , +indicating that the file descriptor is readable, and +.BR POLLHUP , +indicating that the other end of the FIFO has been closed. +The program then consumed some of the available input. +.IP \[bu] +The second return from +.BR poll () +also indicated +.B POLLIN +and +.BR POLLHUP ; +the program then consumed the last of the available input. +.IP \[bu] +On the final return, +.BR poll () +indicated only +.B POLLHUP +on the FIFO, +at which point the file descriptor was closed and the program terminated. +.\" +.SS Program source +\& +.\" SRC BEGIN (poll_input.c) +.EX +/* poll_input.c +\& + Licensed under GNU General Public License v2 or later. +*/ +#include <fcntl.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +\& +#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e + } while (0) +\& +int +main(int argc, char *argv[]) +{ + int ready; + char buf[10]; + nfds_t num_open_fds, nfds; + ssize_t s; + struct pollfd *pfds; +\& + if (argc < 2) { + fprintf(stderr, "Usage: %s file...\en", argv[0]); + exit(EXIT_FAILURE); + } +\& + num_open_fds = nfds = argc \- 1; + pfds = calloc(nfds, sizeof(struct pollfd)); + if (pfds == NULL) + errExit("malloc"); +\& + /* Open each file on command line, and add it to \[aq]pfds\[aq] array. */ +\& + for (nfds_t j = 0; j < nfds; j++) { + pfds[j].fd = open(argv[j + 1], O_RDONLY); + if (pfds[j].fd == \-1) + errExit("open"); +\& + printf("Opened \e"%s\e" on fd %d\en", argv[j + 1], pfds[j].fd); +\& + pfds[j].events = POLLIN; + } +\& + /* Keep calling poll() as long as at least one file descriptor is + open. */ +\& + while (num_open_fds > 0) { + printf("About to poll()\en"); + ready = poll(pfds, nfds, \-1); + if (ready == \-1) + errExit("poll"); +\& + printf("Ready: %d\en", ready); +\& + /* Deal with array returned by poll(). */ +\& + for (nfds_t j = 0; j < nfds; j++) { + if (pfds[j].revents != 0) { + printf(" fd=%d; events: %s%s%s\en", pfds[j].fd, + (pfds[j].revents & POLLIN) ? "POLLIN " : "", + (pfds[j].revents & POLLHUP) ? "POLLHUP " : "", + (pfds[j].revents & POLLERR) ? "POLLERR " : ""); +\& + if (pfds[j].revents & POLLIN) { + s = read(pfds[j].fd, buf, sizeof(buf)); + if (s == \-1) + errExit("read"); + printf(" read %zd bytes: %.*s\en", + s, (int) s, buf); + } else { /* POLLERR | POLLHUP */ + printf(" closing fd %d\en", pfds[j].fd); + if (close(pfds[j].fd) == \-1) + errExit("close"); + num_open_fds\-\-; + } + } + } + } +\& + printf("All file descriptors closed; bye\en"); + exit(EXIT_SUCCESS); +} +.EE +.\" SRC END +.SH SEE ALSO +.BR restart_syscall (2), +.BR select (2), +.BR select_tut (2), +.BR timespec (3), +.BR epoll (7), +.BR time (7) |