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

select(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)select 23 / 142(_newselect) / - / 142(_newselect); pselect6 270 / 308 / 72 / 335; pselect6_time64 413 (i386 + arm32); i386 82 is the oldselect slot (hub + ledger + cached tables)
Since (kernel)2.0 (hub)
Man pageman2/select.2 (cached roff, dated 2021-03-22); pselect6.2, pselect.2, _newselect.2 are .so aliases of select.2
glibc wrapperyes; pselect needs _POSIX_C_SOURCE >= 200112L; glibc pselect maps to the pselect6 syscall with wrapper differences (below)
Aliases coveredpselect6 (SC-pselect6), _newselect (SC-_newselect), oldselect slot note; pselect6_time64 twin (SC-pselect6_time64)
Ledger IDSC-select

Purpose

select() monitors up to nfds file descriptors in three fd_set classes – readable, writable, exceptional – until one is ready, a signal arrives, or timeout expires. pselect() adds nanosecond precision and an atomically swapped sigmask, closing the signal-vs-fd race. WARNING from select.2: fds must be below FD_SETSIZE (1024), “an unreasonably low limit” that will not change; use poll or epoll_wait instead.

Synopsis

#include <sys/select.h>
int select(int nfds, fd_set *restrict readfds,
           fd_set *restrict writefds, fd_set *restrict exceptfds,
           struct timeval *restrict timeout);
int pselect(int nfds, fd_set *restrict readfds,
            fd_set *restrict writefds, fd_set *restrict exceptfds,
            const struct timespec *restrict timeout,
            const sigset_t *restrict sigmask);

Arguments and behavior

The sets are manipulated with FD_ZERO/FD_SET/FD_CLR/FD_ISSET and are value-result: select() modifies them in place, so a loop must reinitialize them each call. nfds is the highest fd number plus 1. timeout is a struct timeval; NULL means infinite, both fields zero means pure poll. Linux modifies timeout to the time not slept (even on EINTR) – do not rely on it; the glibc pselect wrapper hides the kernel-side mutation with a local copy. pselect6 kernel ABI: the last argument is not sigset_t* but a struct { const kernel_sigset_t *ss; size_t ss_len; } so pointer and size fit in one slot (select.2).

Return value and errors

Count of ready fds across the three sets (0 on timeout); -1 with errno and the sets unmodified: EBADF (invalid fd in a set; see BUGS), EINTR, EINVAL (nfds negative or above RLIMIT_NOFILE; bad timeout value), ENOMEM.

Flags and constants

FD_SETSIZE is fixed at 1024 in glibc (kernel imposes no such limit); FD_SET/FD_CLR beyond it is undefined behavior. Kernel notification mapping (fs/select.c via select.2): read = EPOLLRDNORM|EPOLLRDBAND| EPOLLIN|EPOLLHUP|EPOLLERR; write = EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT| EPOLLERR; except = EPOLLPRI.

Security and notes

Numbering honesty (worklog 1-g): the modern i386 select is the _newselect syscall (142, kernel name sys_select; ledger SC-_newselect researched; _newselect.2 is a .so alias); ledger SC-select’s i386 82 is sys_old_select, the legacy slot, and x64 has plain select 23; oldselect has no SC-row of its own (ledger correction note). glibc history (select.2): 2.0 shipped a broken pselect without sigmask; 2.1-2.2.1 needed _GNU_SOURCE; the 2.1-era sigprocmask+select emulation kept the race pselect was meant to fix – modern glibc uses the pselect6 syscall (kernel 2.6.16+). musl 1.2.5 (src/select/select.c, worklog 1-g) is time64-first: it dispatches to SYS_pselect6_time64 (413) and falls back to SYS_select only for small timeouts on old kernels. Spurious readiness and other-thread close pitfalls: Linux may report a socket readable yet a later read can still block – use O_NONBLOCK (select.2 BUGS/NOTES).

References

  • Cached man page: source-cache/man-pages-sparse/man2/select.2 (pselect6.2/pselect.2/_newselect.2 .so).
  • Numbers: hub overview.md, ledger.md; source-cache/kernel/syscall_{64,32,generic,arm}.tbl.
  • musl dispatch: source-cache/musl-clone/musl/src/select/select.c (worklog 1-g).
  • Worklog Task 1-g (_newselect/oldselect slot disambiguation).