Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

poll(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)poll 7 / 168 / - / 168; ppoll 271 / 309(time32) / 73 / 336(time32); ppoll_time64 414 (i386 + arm32) (hub + cached tables)
Since (kernel)poll: 2.0.36 per hub/syscalls(2) vs 2.1.23 per poll.2 VERSIONS (both recorded; worklog 1-g conflict). ppoll 2.6.16 (poll.2). ppoll_time64 5.1 (tag probe, worklog 1-g)
Man pageman2/poll.2 (cached roff, dated 2021-03-22; ppoll.2 is a .so alias)
glibc wrapperyes; glibc poll() emulates via select(2) on kernels lacking poll (poll.2); ppoll library call glibc 2.4
Aliases coveredppoll (SC-ppoll) + ppoll_time64 twin (SC-ppoll_time64)
Ledger IDSC-poll

Purpose

poll() waits for one of a set of file descriptors to become ready to perform I/O – the fixed-size alternative to select and the portable precursor of epoll_wait. ppoll() adds a timespec timeout and an atomic sigmask swap, making it the poll analogue of pselect (poll.2).

Synopsis

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
int ppoll(struct pollfd *fds, nfds_t nfds,
          const struct timespec *tmo_p, const sigset_t *sigmask);

Arguments and behavior

fds is an array of struct pollfd { int fd; short events; short revents; }. A negative fd is ignored (revents 0); events may be 0 to only receive POLLHUP/POLLERR/POLLNVAL. timeout in milliseconds: -1 infinite, 0 immediate return. ppoll’s tmo_p is a timespec (NULL = infinite); a negative timespec is an EINVAL error for ppoll, unlike poll’s negative timeout (poll.2). With sigmask NULL, ppoll differs from poll only in timeout precision; otherwise it atomically sigprocmask(SIG_SETMASK)s, polls, and restores – the pselect race-window fix. The raw ppoll syscall mutates *tmo_p (glibc hides this with a local copy) and takes a fifth argument sigsetsize.

Return value and errors

Nonnegative count of fds with nonzero revents; 0 on timeout; -1 with errno: EFAULT, EINTR, EINVAL (nfds exceeds RLIMIT_NOFILE; ppoll negative timeout), ENOMEM. Linux returns ENOMEM where some systems return EAGAIN; portable code loops on both (poll.2 NOTES).

Flags and constants

BitSinceMeaning
POLLIN-data to read
POLLPRI-exceptional condition (TCP OOB, pty packet mode, cgroup.events)
POLLOUT-writable (large writes may still block)
POLLRDHUP2.6.17stream peer closed/shut write half (_GNU_SOURCE)
POLLERR / POLLHUP / POLLNVAL-output-only in revents

_XOPEN_SOURCE adds POLLRDNORM/POLLRDBAND/POLLWRNORM/POLLWRBAND (synonyms); POLLMSG is known but unused (poll.2). O_NONBLOCK does not affect poll/ppoll readiness semantics.

Security and notes

Since conflict recorded per worklog 1-g: the hub/ledger carry 2.0.36 (syscalls(2) table) while poll.2 VERSIONS says “introduced in Linux 2.1.23” with glibc select-based emulation for older kernels. Closing a monitored fd in another thread has unspecified effect (poll.2 -> select.2). ppoll_time64 twin: i386/arm 414, added 5.1 (worklog 1-e syscall_32.tbl v5.0/v5.1 probe); takes __kernel_timespec for 64-bit tv_sec on 32-bit. The hub splits ppoll into ppoll.md; this task keeps it here – merge-time pointer decision.

References

  • Cached man page: source-cache/man-pages-sparse/man2/poll.2 (ppoll.2 .so).
  • Numbers: hub overview.md, ledger.md; source-cache/kernel/syscall_{64,32,generic,arm}.tbl.
  • Worklog Tasks 1-e/1-g (time64 since-date probe; 2.0.36 vs 2.1.23 conflict).