Blame man2/select.2

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/.