|
Packit |
7cfc04 |
.\" This manpage is copyright (C) 1992 Drew Eckhardt,
|
|
Packit |
7cfc04 |
.\" copyright (C) 1995 Michael Shields.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" %%%LICENSE_START(VERBATIM)
|
|
Packit |
7cfc04 |
.\" Permission is granted to make and distribute verbatim copies of this
|
|
Packit |
7cfc04 |
.\" manual provided the copyright notice and this permission notice are
|
|
Packit |
7cfc04 |
.\" preserved on all copies.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" Permission is granted to copy and distribute modified versions of this
|
|
Packit |
7cfc04 |
.\" manual under the conditions for verbatim copying, provided that the
|
|
Packit |
7cfc04 |
.\" entire resulting derived work is distributed under the terms of a
|
|
Packit |
7cfc04 |
.\" permission notice identical to this one.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
Packit |
7cfc04 |
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
Packit |
7cfc04 |
.\" responsibility for errors or omissions, or for damages resulting from
|
|
Packit |
7cfc04 |
.\" the use of the information contained herein. The author(s) may not
|
|
Packit |
7cfc04 |
.\" have taken the same level of care in the production of this manual,
|
|
Packit |
7cfc04 |
.\" which is licensed free of charge, as they might when working
|
|
Packit |
7cfc04 |
.\" professionally.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
Packit |
7cfc04 |
.\" the source, must acknowledge the copyright and authors of this work.
|
|
Packit |
7cfc04 |
.\" %%%LICENSE_END
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" Modified 1993-07-24 by Rik Faith <faith@cs.unc.edu>
|
|
Packit |
7cfc04 |
.\" Modified 1995-05-18 by Jim Van Zandt <jrv@vanzandt.mv.com>
|
|
Packit |
7cfc04 |
.\" Sun Feb 11 14:07:00 MET 1996 Martin Schulze <joey@linux.de>
|
|
Packit |
7cfc04 |
.\" * layout slightly modified
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" Modified Mon Oct 21 23:05:29 EDT 1996 by Eric S. Raymond <esr@thyrsus.com>
|
|
Packit |
7cfc04 |
.\" Modified Thu Feb 24 01:41:09 CET 2000 by aeb
|
|
Packit |
7cfc04 |
.\" Modified Thu Feb 9 22:32:09 CET 2001 by bert hubert <ahu@ds9a.nl>, aeb
|
|
Packit |
7cfc04 |
.\" Modified Mon Nov 11 14:35:00 PST 2002 by Ben Woodard <ben@zork.net>
|
|
Packit |
7cfc04 |
.\" 2005-03-11, mtk, modified pselect() text (it is now a system
|
|
Packit |
7cfc04 |
.\" call in 2.6.16.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.TH SELECT 2 2017-09-15 "Linux" "Linux Programmer's Manual"
|
|
Packit |
7cfc04 |
.SH NAME
|
|
Packit |
7cfc04 |
select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO \-
|
|
Packit |
7cfc04 |
synchronous I/O multiplexing
|
|
Packit |
7cfc04 |
.SH SYNOPSIS
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
/* According to POSIX.1-2001, POSIX.1-2008 */
|
|
Packit |
7cfc04 |
.B #include <sys/select.h>
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
/* According to earlier standards */
|
|
Packit |
7cfc04 |
.B #include <sys/time.h>
|
|
Packit |
7cfc04 |
.B #include <sys/types.h>
|
|
Packit |
7cfc04 |
.B #include <unistd.h>
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BI "int select(int " nfds ", fd_set *" readfds ", fd_set *" writefds ,
|
|
Packit |
7cfc04 |
.BI " fd_set *" exceptfds ", struct timeval *" timeout );
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BI "void FD_CLR(int " fd ", fd_set *" set );
|
|
Packit |
7cfc04 |
.BI "int FD_ISSET(int " fd ", fd_set *" set );
|
|
Packit |
7cfc04 |
.BI "void FD_SET(int " fd ", fd_set *" set );
|
|
Packit |
7cfc04 |
.BI "void FD_ZERO(fd_set *" set );
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
.B #include <sys/select.h>
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BI "int pselect(int " nfds ", fd_set *" readfds ", fd_set *" writefds ,
|
|
Packit |
7cfc04 |
.BI " fd_set *" exceptfds ", const struct timespec *" timeout ,
|
|
Packit |
7cfc04 |
.BI " const sigset_t *" sigmask );
|
|
Packit |
7cfc04 |
.fi
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in -4n
|
|
Packit |
7cfc04 |
Feature Test Macro Requirements for glibc (see
|
|
Packit |
7cfc04 |
.BR feature_test_macros (7)):
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BR pselect ():
|
|
Packit |
7cfc04 |
_POSIX_C_SOURCE\ >=\ 200112L
|
|
Packit |
7cfc04 |
.SH DESCRIPTION
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
allow a program to monitor multiple file descriptors,
|
|
Packit |
7cfc04 |
waiting until one or more of the file descriptors become "ready"
|
|
Packit |
7cfc04 |
for some class of I/O operation (e.g., input possible).
|
|
Packit |
7cfc04 |
A file descriptor is considered ready if it is possible to
|
|
Packit |
7cfc04 |
perform a corresponding I/O operation (e.g.,
|
|
Packit |
7cfc04 |
.BR read (2)
|
|
Packit |
7cfc04 |
without blocking, or a sufficiently small
|
|
Packit |
7cfc04 |
.BR write (2)).
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
can monitor only file descriptors numbers that are less than
|
|
Packit |
7cfc04 |
.BR FD_SETSIZE ;
|
|
Packit |
7cfc04 |
.BR poll (2)
|
|
Packit |
7cfc04 |
does not have this limitation.
|
|
Packit |
7cfc04 |
See BUGS.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The operation of
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
is identical, other than these three differences:
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
(i)
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
uses a timeout that is a
|
|
Packit |
7cfc04 |
.I struct timeval
|
|
Packit |
7cfc04 |
(with seconds and microseconds), while
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
uses a
|
|
Packit |
7cfc04 |
.I struct timespec
|
|
Packit |
7cfc04 |
(with seconds and nanoseconds).
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
(ii)
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
may update the
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
argument to indicate how much time was left.
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
does not change this argument.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
(iii)
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
has no
|
|
Packit |
7cfc04 |
.I sigmask
|
|
Packit |
7cfc04 |
argument, and behaves as
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
called with NULL
|
|
Packit |
7cfc04 |
.IR sigmask .
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Three independent sets of file descriptors are watched.
|
|
Packit |
7cfc04 |
The file descriptors listed in
|
|
Packit |
7cfc04 |
.I readfds
|
|
Packit |
7cfc04 |
will be watched to see if characters become
|
|
Packit |
7cfc04 |
available for reading (more precisely, to see if a read will not
|
|
Packit |
7cfc04 |
block; in particular, a file descriptor is also ready on end-of-file).
|
|
Packit |
7cfc04 |
The file descriptors in
|
|
Packit |
7cfc04 |
.I writefds
|
|
Packit |
7cfc04 |
will be watched to see if space is available for write (though a large
|
|
Packit |
7cfc04 |
write may still block).
|
|
Packit |
7cfc04 |
The file descriptors in
|
|
Packit |
7cfc04 |
.I exceptfds
|
|
Packit |
7cfc04 |
will be watched for exceptional conditions.
|
|
Packit |
7cfc04 |
(For examples of some exceptional conditions, see the discussion of
|
|
Packit |
7cfc04 |
.B POLLPRI
|
|
Packit |
7cfc04 |
in
|
|
Packit |
7cfc04 |
.BR poll (2).)
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
On exit, each of the file descriptor sets is modified in place
|
|
Packit |
7cfc04 |
to indicate which file descriptors actually changed status.
|
|
Packit |
7cfc04 |
(Thus, if using
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
within a loop, the sets must be reinitialized before each call.)
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Each of the three file descriptor sets may be specified as NULL
|
|
Packit |
7cfc04 |
if no file descriptors are to be watched for the corresponding class
|
|
Packit |
7cfc04 |
of events.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Four macros are provided to manipulate the sets.
|
|
Packit |
7cfc04 |
.BR FD_ZERO ()
|
|
Packit |
7cfc04 |
clears a set.
|
|
Packit |
7cfc04 |
.BR FD_SET ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR FD_CLR ()
|
|
Packit |
7cfc04 |
respectively add and remove a given file descriptor from a set.
|
|
Packit |
7cfc04 |
.BR FD_ISSET ()
|
|
Packit |
7cfc04 |
tests to see if a file descriptor is part of the set;
|
|
Packit |
7cfc04 |
this is useful after
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
returns.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.I nfds
|
|
Packit |
7cfc04 |
should be set to the highest-numbered file descriptor in any
|
|
Packit |
7cfc04 |
of the three sets, plus 1.
|
|
Packit |
7cfc04 |
The indicated file descriptors in each set are checked, up to this limit
|
|
Packit |
7cfc04 |
(but see BUGS).
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
argument specifies the interval that
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
should block waiting for a file descriptor to become ready.
|
|
Packit |
7cfc04 |
The call will block until either:
|
|
Packit |
7cfc04 |
.IP * 3
|
|
Packit |
7cfc04 |
a file descriptor becomes ready;
|
|
Packit |
7cfc04 |
.IP *
|
|
Packit |
7cfc04 |
the call is interrupted by a signal handler; or
|
|
Packit |
7cfc04 |
.IP *
|
|
Packit |
7cfc04 |
the timeout expires.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Note that the
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
interval will be rounded up to the system clock granularity,
|
|
Packit |
7cfc04 |
and kernel scheduling delays mean that the blocking interval
|
|
Packit |
7cfc04 |
may overrun by a small amount.
|
|
Packit |
7cfc04 |
If both fields of the
|
|
Packit |
7cfc04 |
.I timeval
|
|
Packit |
7cfc04 |
structure are zero, then
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
returns immediately.
|
|
Packit |
7cfc04 |
(This is useful for polling.)
|
|
Packit |
7cfc04 |
If
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
is NULL (no timeout),
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
can block indefinitely.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.I sigmask
|
|
Packit |
7cfc04 |
is a pointer to a signal mask (see
|
|
Packit |
7cfc04 |
.BR sigprocmask (2));
|
|
Packit |
7cfc04 |
if it is not NULL, then
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
first replaces the current signal mask by the one pointed to by
|
|
Packit |
7cfc04 |
.IR sigmask ,
|
|
Packit |
7cfc04 |
then does the "select" function, and then restores the original
|
|
Packit |
7cfc04 |
signal mask.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Other than the difference in the precision of the
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
argument, the following
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
call:
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
ready = pselect(nfds, &readfds, &writefds, &exceptfds,
|
|
Packit |
7cfc04 |
timeout, &sigmask);
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
is equivalent to
|
|
Packit |
7cfc04 |
.I atomically
|
|
Packit |
7cfc04 |
executing the following calls:
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
sigset_t origmask;
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
|
|
Packit |
7cfc04 |
ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
|
|
Packit |
7cfc04 |
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The reason that
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
is needed is that if one wants to wait for either a signal
|
|
Packit |
7cfc04 |
or for a file descriptor to become ready, then
|
|
Packit |
7cfc04 |
an atomic test is needed to prevent race conditions.
|
|
Packit |
7cfc04 |
(Suppose the signal handler sets a global flag and
|
|
Packit |
7cfc04 |
returns.
|
|
Packit |
7cfc04 |
Then a test of this global flag followed by a call of
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
could hang indefinitely if the signal arrived just after the test
|
|
Packit |
7cfc04 |
but just before the call.
|
|
Packit |
7cfc04 |
By contrast,
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
allows one to first block signals, handle the signals that have come in,
|
|
Packit |
7cfc04 |
then call
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
with the desired
|
|
Packit |
7cfc04 |
.IR sigmask ,
|
|
Packit |
7cfc04 |
avoiding the race.)
|
|
Packit |
7cfc04 |
.SS The timeout
|
|
Packit |
7cfc04 |
The time structures involved are defined in
|
|
Packit |
7cfc04 |
.I <sys/time.h>
|
|
Packit |
7cfc04 |
and look like
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
struct timeval {
|
|
Packit |
7cfc04 |
long tv_sec; /* seconds */
|
|
Packit |
7cfc04 |
long tv_usec; /* microseconds */
|
|
Packit |
7cfc04 |
};
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
struct timespec {
|
|
Packit |
7cfc04 |
long tv_sec; /* seconds */
|
|
Packit |
7cfc04 |
long tv_nsec; /* nanoseconds */
|
|
Packit |
7cfc04 |
};
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
(However, see below on the POSIX.1 versions.)
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Some code calls
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
with all three sets empty,
|
|
Packit |
7cfc04 |
.I nfds
|
|
Packit |
7cfc04 |
zero, and a non-NULL
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
as a fairly portable way to sleep with subsecond precision.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
On Linux,
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
modifies
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
to reflect the amount of time not slept; most other implementations
|
|
Packit |
7cfc04 |
do not do this.
|
|
Packit |
7cfc04 |
(POSIX.1 permits either behavior.)
|
|
Packit |
7cfc04 |
This causes problems both when Linux code which reads
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
is ported to other operating systems, and when code is ported to Linux
|
|
Packit |
7cfc04 |
that reuses a \fIstruct timeval\fP for multiple
|
|
Packit |
7cfc04 |
.BR select ()s
|
|
Packit |
7cfc04 |
in a loop without reinitializing it.
|
|
Packit |
7cfc04 |
Consider
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
to be undefined after
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
returns.
|
|
Packit |
7cfc04 |
.\" .PP - it is rumored that:
|
|
Packit |
7cfc04 |
.\" On BSD, when a timeout occurs, the file descriptor bits are not changed.
|
|
Packit |
7cfc04 |
.\" - it is certainly true that:
|
|
Packit |
7cfc04 |
.\" Linux follows SUSv2 and sets the bit masks to zero upon a timeout.
|
|
Packit |
7cfc04 |
.SH RETURN VALUE
|
|
Packit |
7cfc04 |
On success,
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
return the number of file descriptors contained in the three returned
|
|
Packit |
7cfc04 |
descriptor sets (that is, the total number of bits that are set in
|
|
Packit |
7cfc04 |
.IR readfds ,
|
|
Packit |
7cfc04 |
.IR writefds ,
|
|
Packit |
7cfc04 |
.IR exceptfds )
|
|
Packit |
7cfc04 |
which may be zero if the timeout expires before anything interesting happens.
|
|
Packit |
7cfc04 |
On error, \-1 is returned, and
|
|
Packit |
7cfc04 |
.I errno
|
|
Packit |
7cfc04 |
is set to indicate the error;
|
|
Packit |
7cfc04 |
the file descriptor sets are unmodified,
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
becomes undefined.
|
|
Packit |
7cfc04 |
.SH ERRORS
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EBADF
|
|
Packit |
7cfc04 |
An invalid file descriptor was given in one of the sets.
|
|
Packit |
7cfc04 |
(Perhaps a file descriptor that was already closed,
|
|
Packit |
7cfc04 |
or one on which an error has occurred.)
|
|
Packit |
7cfc04 |
However, see BUGS.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EINTR
|
|
Packit |
7cfc04 |
A signal was caught; see
|
|
Packit |
7cfc04 |
.BR signal (7).
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EINVAL
|
|
Packit |
7cfc04 |
.I nfds
|
|
Packit |
7cfc04 |
is negative or exceeds the
|
|
Packit |
7cfc04 |
.BR RLIMIT_NOFILE
|
|
Packit |
7cfc04 |
resource limit (see
|
|
Packit |
7cfc04 |
.BR getrlimit (2)).
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EINVAL
|
|
Packit |
7cfc04 |
The value contained within
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
is invalid.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B ENOMEM
|
|
Packit |
7cfc04 |
Unable to allocate memory for internal tables.
|
|
Packit |
7cfc04 |
.SH VERSIONS
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
was added to Linux in kernel 2.6.16.
|
|
Packit |
7cfc04 |
Prior to this,
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
was emulated in glibc (but see BUGS).
|
|
Packit |
7cfc04 |
.SH CONFORMING TO
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
conforms to POSIX.1-2001, POSIX.1-2008, and
|
|
Packit |
7cfc04 |
4.4BSD
|
|
Packit |
7cfc04 |
.RB ( select ()
|
|
Packit |
7cfc04 |
first appeared in 4.2BSD).
|
|
Packit |
7cfc04 |
Generally portable to/from
|
|
Packit |
7cfc04 |
non-BSD systems supporting clones of the BSD socket layer (including
|
|
Packit |
7cfc04 |
System\ V variants).
|
|
Packit |
7cfc04 |
However, note that the System\ V variant typically
|
|
Packit |
7cfc04 |
sets the timeout variable before exit, but the BSD variant does not.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
is defined in POSIX.1g, and in
|
|
Packit |
7cfc04 |
POSIX.1-2001 and POSIX.1-2008.
|
|
Packit |
7cfc04 |
.SH NOTES
|
|
Packit |
7cfc04 |
An
|
|
Packit |
7cfc04 |
.I fd_set
|
|
Packit |
7cfc04 |
is a fixed size buffer.
|
|
Packit |
7cfc04 |
Executing
|
|
Packit |
7cfc04 |
.BR FD_CLR ()
|
|
Packit |
7cfc04 |
or
|
|
Packit |
7cfc04 |
.BR FD_SET ()
|
|
Packit |
7cfc04 |
with a value of
|
|
Packit |
7cfc04 |
.I fd
|
|
Packit |
7cfc04 |
that is negative or is equal to or larger than
|
|
Packit |
7cfc04 |
.B FD_SETSIZE
|
|
Packit |
7cfc04 |
will result
|
|
Packit |
7cfc04 |
in undefined behavior.
|
|
Packit |
7cfc04 |
Moreover, POSIX requires
|
|
Packit |
7cfc04 |
.I fd
|
|
Packit |
7cfc04 |
to be a valid file descriptor.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
On some other UNIX systems,
|
|
Packit |
7cfc04 |
.\" Darwin, according to a report by Jeremy Sequoia, relayed by Josh Triplett
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
can fail with the error
|
|
Packit |
7cfc04 |
.B EAGAIN
|
|
Packit |
7cfc04 |
if the system fails to allocate kernel-internal resources, rather than
|
|
Packit |
7cfc04 |
.B ENOMEM
|
|
Packit |
7cfc04 |
as Linux does.
|
|
Packit |
7cfc04 |
POSIX specifies this error for
|
|
Packit |
7cfc04 |
.BR poll (2),
|
|
Packit |
7cfc04 |
but not for
|
|
Packit |
7cfc04 |
.BR select ().
|
|
Packit |
7cfc04 |
Portable programs may wish to check for
|
|
Packit |
7cfc04 |
.B EAGAIN
|
|
Packit |
7cfc04 |
and loop, just as with
|
|
Packit |
7cfc04 |
.BR EINTR .
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
On systems that lack
|
|
Packit |
7cfc04 |
.BR pselect (),
|
|
Packit |
7cfc04 |
reliable (and more portable) signal trapping can be achieved
|
|
Packit |
7cfc04 |
using the self-pipe trick.
|
|
Packit |
7cfc04 |
In this technique,
|
|
Packit |
7cfc04 |
a signal handler writes a byte to a pipe whose other end
|
|
Packit |
7cfc04 |
is monitored by
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
in the main program.
|
|
Packit |
7cfc04 |
(To avoid possibly blocking when writing to a pipe that may be full
|
|
Packit |
7cfc04 |
or reading from a pipe that may be empty,
|
|
Packit |
7cfc04 |
nonblocking I/O is used when reading from and writing to the pipe.)
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Concerning the types involved, the classical situation is that
|
|
Packit |
7cfc04 |
the two fields of a
|
|
Packit |
7cfc04 |
.I timeval
|
|
Packit |
7cfc04 |
structure are typed as
|
|
Packit |
7cfc04 |
.I long
|
|
Packit |
7cfc04 |
(as shown above), and the structure is defined in
|
|
Packit |
7cfc04 |
.IR <sys/time.h> .
|
|
Packit |
7cfc04 |
The POSIX.1 situation is
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
struct timeval {
|
|
Packit |
7cfc04 |
time_t tv_sec; /* seconds */
|
|
Packit |
7cfc04 |
suseconds_t tv_usec; /* microseconds */
|
|
Packit |
7cfc04 |
};
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
where the structure is defined in
|
|
Packit |
7cfc04 |
.I <sys/select.h>
|
|
Packit |
7cfc04 |
and the data types
|
|
Packit |
7cfc04 |
.I time_t
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.I suseconds_t
|
|
Packit |
7cfc04 |
are defined in
|
|
Packit |
7cfc04 |
.IR <sys/types.h> .
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Concerning prototypes, the classical situation is that one should
|
|
Packit |
7cfc04 |
include
|
|
Packit |
7cfc04 |
.I <time.h>
|
|
Packit |
7cfc04 |
for
|
|
Packit |
7cfc04 |
.BR select ().
|
|
Packit |
7cfc04 |
The POSIX.1 situation is that one should include
|
|
Packit |
7cfc04 |
.I <sys/select.h>
|
|
Packit |
7cfc04 |
for
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR pselect ().
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Under glibc 2.0,
|
|
Packit |
7cfc04 |
.I <sys/select.h>
|
|
Packit |
7cfc04 |
gives the wrong prototype for
|
|
Packit |
7cfc04 |
.BR pselect ().
|
|
Packit |
7cfc04 |
Under glibc 2.1 to 2.2.1, it gives
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
when
|
|
Packit |
7cfc04 |
.B _GNU_SOURCE
|
|
Packit |
7cfc04 |
is defined.
|
|
Packit |
7cfc04 |
Since glibc 2.2.2, the requirements are as shown in the SYNOPSIS.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.SS Correspondence between select() and poll() notifications
|
|
Packit |
7cfc04 |
Within the Linux kernel source,
|
|
Packit |
7cfc04 |
.\" fs/select.c
|
|
Packit |
7cfc04 |
we find the following definitions which show the correspondence
|
|
Packit |
7cfc04 |
between the readable, writable, and exceptional condition notifications of
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
and the event notifications provided by
|
|
Packit |
7cfc04 |
.BR poll (2)
|
|
Packit |
7cfc04 |
(and
|
|
Packit |
7cfc04 |
.BR epoll (7)):
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP |
|
|
Packit |
7cfc04 |
POLLERR)
|
|
Packit |
7cfc04 |
/* Ready for reading */
|
|
Packit |
7cfc04 |
#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
|
|
Packit |
7cfc04 |
/* Ready for writing */
|
|
Packit |
7cfc04 |
#define POLLEX_SET (POLLPRI)
|
|
Packit |
7cfc04 |
/* Exceptional condition */
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.SS Multithreaded applications
|
|
Packit |
7cfc04 |
If a file descriptor being monitored by
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
is closed in another thread, the result is unspecified.
|
|
Packit |
7cfc04 |
On some UNIX systems,
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
unblocks and returns, with an indication that the file descriptor is ready
|
|
Packit |
7cfc04 |
(a subsequent I/O operation will likely fail with an error,
|
|
Packit |
7cfc04 |
unless another the file descriptor reopened between the time
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
returned and the I/O operations was performed).
|
|
Packit |
7cfc04 |
On Linux (and some other systems),
|
|
Packit |
7cfc04 |
closing the file descriptor in another thread has no effect on
|
|
Packit |
7cfc04 |
.BR select ().
|
|
Packit |
7cfc04 |
In summary, any application that relies on a particular behavior
|
|
Packit |
7cfc04 |
in this scenario must be considered buggy.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.SS C library/kernel differences
|
|
Packit |
7cfc04 |
The Linux kernel allows file descriptor sets of arbitrary size,
|
|
Packit |
7cfc04 |
determining the length of the sets to be checked from the value of
|
|
Packit |
7cfc04 |
.IR nfds .
|
|
Packit |
7cfc04 |
However, in the glibc implementation, the
|
|
Packit |
7cfc04 |
.IR fd_set
|
|
Packit |
7cfc04 |
type is fixed in size.
|
|
Packit |
7cfc04 |
See also BUGS.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
interface described in this page is implemented by glibc.
|
|
Packit |
7cfc04 |
The underlying Linux system call is named
|
|
Packit |
7cfc04 |
.BR pselect6 ().
|
|
Packit |
7cfc04 |
This system call has somewhat different behavior from the glibc
|
|
Packit |
7cfc04 |
wrapper function.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The Linux
|
|
Packit |
7cfc04 |
.BR pselect6 ()
|
|
Packit |
7cfc04 |
system call modifies its
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
argument.
|
|
Packit |
7cfc04 |
However, the glibc wrapper function hides this behavior
|
|
Packit |
7cfc04 |
by using a local variable for the timeout argument that
|
|
Packit |
7cfc04 |
is passed to the system call.
|
|
Packit |
7cfc04 |
Thus, the glibc
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
function does not modify its
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
argument;
|
|
Packit |
7cfc04 |
this is the behavior required by POSIX.1-2001.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The final argument of the
|
|
Packit |
7cfc04 |
.BR pselect6 ()
|
|
Packit |
7cfc04 |
system call is not a
|
|
Packit |
7cfc04 |
.I "sigset_t\ *"
|
|
Packit |
7cfc04 |
pointer, but is instead a structure of the form:
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
struct {
|
|
Packit |
7cfc04 |
const kernel_sigset_t *ss; /* Pointer to signal set */
|
|
Packit |
7cfc04 |
size_t ss_len; /* Size (in bytes) of object
|
|
Packit |
7cfc04 |
pointed to by 'ss' */
|
|
Packit |
7cfc04 |
};
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
This allows the system call to obtain both
|
|
Packit |
7cfc04 |
a pointer to the signal set and its size,
|
|
Packit |
7cfc04 |
while allowing for the fact that most architectures
|
|
Packit |
7cfc04 |
support a maximum of 6 arguments to a system call.
|
|
Packit |
7cfc04 |
See
|
|
Packit |
7cfc04 |
.BR sigprocmask (2)
|
|
Packit |
7cfc04 |
for a discussion of the difference between the kernel and libc
|
|
Packit |
7cfc04 |
notion of the signal set.
|
|
Packit |
7cfc04 |
.SH BUGS
|
|
Packit |
7cfc04 |
POSIX allows an implementation to define an upper limit,
|
|
Packit |
7cfc04 |
advertised via the constant
|
|
Packit |
7cfc04 |
.BR FD_SETSIZE ,
|
|
Packit |
7cfc04 |
on the range of file descriptors that can be specified
|
|
Packit |
7cfc04 |
in a file descriptor set.
|
|
Packit |
7cfc04 |
The Linux kernel imposes no fixed limit, but the glibc implementation makes
|
|
Packit |
7cfc04 |
.IR fd_set
|
|
Packit |
7cfc04 |
a fixed-size type, with
|
|
Packit |
7cfc04 |
.BR FD_SETSIZE
|
|
Packit |
7cfc04 |
defined as 1024, and the
|
|
Packit |
7cfc04 |
.BR FD_* ()
|
|
Packit |
7cfc04 |
macros operating according to that limit.
|
|
Packit |
7cfc04 |
To monitor file descriptors greater than 1023, use
|
|
Packit |
7cfc04 |
.BR poll (2)
|
|
Packit |
7cfc04 |
instead.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
According to POSIX,
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
should check all specified file descriptors in the three file descriptor sets,
|
|
Packit |
7cfc04 |
up to the limit
|
|
Packit |
7cfc04 |
.IR nfds\-1 .
|
|
Packit |
7cfc04 |
However, the current implementation ignores any file descriptor in
|
|
Packit |
7cfc04 |
these sets that is greater than the maximum file descriptor number
|
|
Packit |
7cfc04 |
that the process currently has open.
|
|
Packit |
7cfc04 |
According to POSIX, any such file descriptor that is specified in one
|
|
Packit |
7cfc04 |
of the sets should result in the error
|
|
Packit |
7cfc04 |
.BR EBADF .
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Glibc 2.0 provided a version of
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
that did not take a
|
|
Packit |
7cfc04 |
.I sigmask
|
|
Packit |
7cfc04 |
argument.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Starting with version 2.1, glibc provided an emulation of
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
that was implemented using
|
|
Packit |
7cfc04 |
.BR sigprocmask (2)
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR select ().
|
|
Packit |
7cfc04 |
This implementation remained vulnerable to the very race condition that
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
was designed to prevent.
|
|
Packit |
7cfc04 |
Modern versions of glibc use the (race-free)
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
system call on kernels where it is provided.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Under Linux,
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
may report a socket file descriptor as "ready for reading", while
|
|
Packit |
7cfc04 |
nevertheless a subsequent read blocks.
|
|
Packit |
7cfc04 |
This could for example
|
|
Packit |
7cfc04 |
happen when data has arrived but upon examination has wrong
|
|
Packit |
7cfc04 |
checksum and is discarded.
|
|
Packit |
7cfc04 |
There may be other circumstances
|
|
Packit |
7cfc04 |
in which a file descriptor is spuriously reported as ready.
|
|
Packit |
7cfc04 |
.\" Stevens discusses a case where accept can block after select
|
|
Packit |
7cfc04 |
.\" returns successfully because of an intervening RST from the client.
|
|
Packit |
7cfc04 |
Thus it may be safer to use
|
|
Packit |
7cfc04 |
.B O_NONBLOCK
|
|
Packit |
7cfc04 |
on sockets that should not block.
|
|
Packit |
7cfc04 |
.\" Maybe the kernel should have returned EIO in such a situation?
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
On Linux,
|
|
Packit |
7cfc04 |
.BR select ()
|
|
Packit |
7cfc04 |
also modifies
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
if the call is interrupted by a signal handler (i.e., the
|
|
Packit |
7cfc04 |
.B EINTR
|
|
Packit |
7cfc04 |
error return).
|
|
Packit |
7cfc04 |
This is not permitted by POSIX.1.
|
|
Packit |
7cfc04 |
The Linux
|
|
Packit |
7cfc04 |
.BR pselect ()
|
|
Packit |
7cfc04 |
system call has the same behavior,
|
|
Packit |
7cfc04 |
but the glibc wrapper hides this behavior by internally copying the
|
|
Packit |
7cfc04 |
.I timeout
|
|
Packit |
7cfc04 |
to a local variable and passing that variable to the system call.
|
|
Packit |
7cfc04 |
.SH EXAMPLE
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
#include <stdio.h>
|
|
Packit |
7cfc04 |
#include <stdlib.h>
|
|
Packit |
7cfc04 |
#include <sys/time.h>
|
|
Packit |
7cfc04 |
#include <sys/types.h>
|
|
Packit |
7cfc04 |
#include <unistd.h>
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
int
|
|
Packit |
7cfc04 |
main(void)
|
|
Packit |
7cfc04 |
{
|
|
Packit |
7cfc04 |
fd_set rfds;
|
|
Packit |
7cfc04 |
struct timeval tv;
|
|
Packit |
7cfc04 |
int retval;
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
/* Watch stdin (fd 0) to see when it has input. */
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
FD_ZERO(&rfds);
|
|
Packit |
7cfc04 |
FD_SET(0, &rfds);
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
/* Wait up to five seconds. */
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
tv.tv_sec = 5;
|
|
Packit |
7cfc04 |
tv.tv_usec = 0;
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
retval = select(1, &rfds, NULL, NULL, &tv;;
|
|
Packit |
7cfc04 |
/* Don't rely on the value of tv now! */
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
if (retval == \-1)
|
|
Packit |
7cfc04 |
perror("select()");
|
|
Packit |
7cfc04 |
else if (retval)
|
|
Packit |
7cfc04 |
printf("Data is available now.\\n");
|
|
Packit |
7cfc04 |
/* FD_ISSET(0, &rfds) will be true. */
|
|
Packit |
7cfc04 |
else
|
|
Packit |
7cfc04 |
printf("No data within five seconds.\\n");
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
exit(EXIT_SUCCESS);
|
|
Packit |
7cfc04 |
}
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.SH SEE ALSO
|
|
Packit |
7cfc04 |
.BR accept (2),
|
|
Packit |
7cfc04 |
.BR connect (2),
|
|
Packit |
7cfc04 |
.BR poll (2),
|
|
Packit |
7cfc04 |
.BR read (2),
|
|
Packit |
7cfc04 |
.BR recv (2),
|
|
Packit |
7cfc04 |
.BR restart_syscall (2),
|
|
Packit |
7cfc04 |
.BR send (2),
|
|
Packit |
7cfc04 |
.BR sigprocmask (2),
|
|
Packit |
7cfc04 |
.BR write (2),
|
|
Packit |
7cfc04 |
.BR epoll (7),
|
|
Packit |
7cfc04 |
.BR time (7)
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
For a tutorial with discussion and examples, see
|
|
Packit |
7cfc04 |
.BR select_tut (2).
|
|
Packit |
7cfc04 |
.SH COLOPHON
|
|
Packit |
7cfc04 |
This page is part of release 4.15 of the Linux
|
|
Packit |
7cfc04 |
.I man-pages
|
|
Packit |
7cfc04 |
project.
|
|
Packit |
7cfc04 |
A description of the project,
|
|
Packit |
7cfc04 |
information about reporting bugs,
|
|
Packit |
7cfc04 |
and the latest version of this page,
|
|
Packit |
7cfc04 |
can be found at
|
|
Packit |
7cfc04 |
\%https://www.kernel.org/doc/man\-pages/.
|