SELECT(2) | System Calls Manual | SELECT(2) |
select
, pselect
,
FD_SET
, FD_CLR
,
FD_ISSET
, FD_ZERO
—
#include <sys/select.h>
int
select
(int
nfds, fd_set
*readfds, fd_set
*writefds, fd_set
*exceptfds, struct
timeval *timeout);
int
pselect
(int
nfds, fd_set
*readfds, fd_set
*writefds, fd_set
*exceptfds, const struct
timespec *timeout, const
sigset_t *mask);
FD_SET
(fd,
&fdset);
FD_CLR
(fd,
&fdset);
FD_ISSET
(fd,
&fdset);
FD_ZERO
(&fdset);
select
() examines the I/O descriptor sets whose
addresses are passed in readfds,
writefds, and exceptfds to see if
some of their descriptors are ready for reading, are ready for writing, or
have an exceptional condition pending, respectively. Exceptional conditions
include the presence of out-of-band data on a socket. The first
nfds descriptors are checked in each set; i.e., the
descriptors from 0 through nfds-1 in the descriptor sets
are examined. On return, select
() replaces the given
descriptor sets with subsets consisting of those descriptors that are ready
for the requested operation. select
() returns the
total number of ready descriptors in all the sets.
The descriptor sets are stored as bit fields in arrays of
integers. The following macros are provided for manipulating such descriptor
sets: FD_ZERO
(&fdset)
initializes a descriptor set fdset to the null set.
FD_SET
(fd,
&fdset) includes a particular descriptor
fd in fdset.
FD_CLR
(fd,
&fdset) removes fd from
fdset.
FD_ISSET
(fd,
&fdset) is non-zero if fd is
a member of fdset, zero otherwise. The behavior of
these macros is undefined if a descriptor value is less than zero or greater
than or equal to FD_SETSIZE
, which is normally at
least equal to the maximum number of descriptors supported by the
system.
If timeout is a non-null pointer, it
specifies a maximum interval to wait for the selection to complete. If
timeout is a null pointer, the select blocks
indefinitely. To effect a poll, the timeout argument
should be non-null, pointing to a zero-valued timeval structure.
timeout is not changed by
select
(), and may be reused on subsequent calls;
however, it is good style to re-initialize it before each invocation of
select
().
Any of readfds, writefds, and exceptfds may be given as null pointers if no descriptors are of interest.
The pselect
() function is similar to
select
() except that it specifies the timeout using
a timespec structure. Also, if mask is a non-null
pointer, pselect
() atomically sets the calling
thread's signal mask to the signal set pointed to by
mask for the duration of the function call. In this
case, the original signal mask will be restored before
pselect
() returns.
select
() and
pselect
() return the number of ready descriptors that
are contained in the descriptor sets. If a descriptor is included in multiple
descriptor sets, each inclusion is counted separately. If the time limit
expires before any descriptors become ready, they return 0.
Otherwise, if select
() or
pselect
() return with an error, including one due to
an interrupted call, they return -1, and the descriptor sets will be
unmodified.
select
() or
pselect
() indicates:
EFAULT
]EBADF
]EINTR
]EINVAL
]EINVAL
]select
() and pselect
()
functions conform to IEEE Std 1003.1-2008
(“POSIX.1”).
select
() system call first appeared in
4.1cBSD. The pselect
() system
call has been available since OpenBSD 5.4.
FD_SETSIZE
(currently 1024),
but that is somewhat smaller than the current kernel limit to the number of
open files. However, in order to accommodate programs which might potentially
use a larger number of open files with select, it is possible to increase this
size within a program by providing a larger definition of
FD_SETSIZE
before the inclusion of any headers. The
kernel will cope, and the userland libraries provided with the system are also
ready for large numbers of file descriptors.
Alternatively, to be really safe, it is possible to allocate fd_set bit-arrays dynamically. The idea is to permit a program to work properly even if it is execve(2)'d with 4000 file descriptors pre-allocated. The following illustrates the technique which is used by userland libraries:
fd_set *fdsr; int max = fd; fdsr = calloc(howmany(max+1, NFDBITS), sizeof(fd_mask)); if (fdsr == NULL) { ... return (-1); } FD_SET(fd, fdsr); n = select(max+1, fdsr, NULL, NULL, &tv); ... free(fdsr);
Alternatively, it is possible to use the
poll(2) interface.
poll(2) is more efficient when the size of
select
()'s fd_set bit-arrays
are very large, and for fixed numbers of file descriptors one need not size
and dynamically allocate a memory object.
select
() should probably have been
designed to return the time remaining from the original timeout, if any, by
modifying the time value in place. Even though some systems stupidly act in
this different way, it is unlikely this semantic will ever be commonly
implemented, as the change causes massive source code compatibility
problems. Furthermore, recent new standards have dictated the current
behaviour. In general, due to the existence of those brain-damaged
non-conforming systems, it is unwise to assume that the timeout value will
be unmodified by the select
() call, and the caller
should reinitialize it on each invocation. Calculating the delta is easily
done by calling gettimeofday(2)
before and after the call to select
(), and using
timersub
() (as described in
getitimer(2)).
Internally to the kernel, select
() and
pselect
() work poorly if multiple processes wait on
the same file descriptor.
September 17, 2016 | OpenBSD-current |