SELECT(2) | System Calls Manual | SELECT(2) |
select
, pselect
,
FD_SET
, FD_CLR
,
FD_ISSET
, FD_ZERO
—
synchronous I/O multiplexing
#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.
If successful, 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.
An error return from select
() or
pselect
() indicates:
EFAULT
]EBADF
]EINTR
]EINVAL
]EINVAL
]accept(2), clock_gettime(2), connect(2), gettimeofday(2), poll(2), read(2), recv(2), send(2), write(2), getdtablesize(3)
The select
() and
pselect
() functions conform to IEEE
Std 1003.1-2008 (“POSIX.1”).
The select
() system call first appeared in
4.1cBSD. The pselect
()
system call has been available since OpenBSD
5.4.
Although the provision of
getdtablesize(3) was intended to
allow user programs to be written independent of the kernel limit on the
number of open files, the dimension of a sufficiently large bit field for
select remains a problem. The default bit size of
fd_set is based on the symbol
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 |