2013-12-06 12:04:52 +01:00
|
|
|
.\" $NetBSD: select.2,v 1.41 2013/11/28 03:45:31 khorben Exp $
|
2011-02-14 20:36:03 +01:00
|
|
|
.\"
|
|
|
|
.\" Copyright (c) 1983, 1991, 1993
|
|
|
|
.\" The Regents of the University of California. All rights reserved.
|
|
|
|
.\"
|
|
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
|
|
.\" modification, are permitted provided that the following conditions
|
|
|
|
.\" are met:
|
|
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
|
|
.\" 3. Neither the name of the University nor the names of its contributors
|
|
|
|
.\" may be used to endorse or promote products derived from this software
|
|
|
|
.\" without specific prior written permission.
|
|
|
|
.\"
|
|
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
.\" SUCH DAMAGE.
|
|
|
|
.\"
|
|
|
|
.\" @(#)select.2 8.2 (Berkeley) 3/25/94
|
|
|
|
.\"
|
2013-12-06 12:04:52 +01:00
|
|
|
.Dd November 28, 2013
|
2011-02-14 20:36:03 +01:00
|
|
|
.Dt SELECT 2
|
|
|
|
.Os
|
|
|
|
.Sh NAME
|
|
|
|
.Nm select ,
|
|
|
|
.Nm pselect
|
|
|
|
.Nd synchronous I/O multiplexing
|
|
|
|
.Sh LIBRARY
|
|
|
|
.Lb libc
|
|
|
|
.Sh SYNOPSIS
|
|
|
|
.In sys/select.h
|
|
|
|
.Ft int
|
|
|
|
.Fn select "int nfds" "fd_set * restrict readfds" "fd_set * restrict writefds" "fd_set * restrict exceptfds" "struct timeval * restrict timeout"
|
|
|
|
.Ft int
|
|
|
|
.Fn 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"
|
|
|
|
.Fn FD_SET "int fd" "fd_set *fdset"
|
|
|
|
.Fn FD_CLR "int fd" "fd_set *fdset"
|
|
|
|
.Fn FD_ISSET "int fd" "fd_set *fdset"
|
|
|
|
.Fn FD_ZERO "fd_set *fdset"
|
|
|
|
.Sh DESCRIPTION
|
|
|
|
.Fn select
|
|
|
|
and
|
|
|
|
.Fn pselect
|
|
|
|
examine the I/O descriptor sets whose addresses are passed in
|
|
|
|
.Fa readfds ,
|
|
|
|
.Fa writefds ,
|
|
|
|
and
|
|
|
|
.Fa exceptfds
|
|
|
|
to see if some of their descriptors
|
|
|
|
are ready for reading, are ready for writing, or have an exceptional
|
|
|
|
condition pending, respectively.
|
|
|
|
The first
|
|
|
|
.Fa nfds
|
|
|
|
descriptors are checked in each set;
|
|
|
|
i.e., the descriptors from 0 through
|
|
|
|
.Fa nfds Ns No \-1
|
|
|
|
in the descriptor sets are examined.
|
|
|
|
This means that
|
|
|
|
.Fa nfds
|
|
|
|
must be set to the highest file descriptor of the three sets, plus one.
|
|
|
|
On return,
|
|
|
|
.Fn select
|
|
|
|
and
|
|
|
|
.Fn pselect
|
|
|
|
replace the given descriptor sets
|
|
|
|
with subsets consisting of those descriptors that are ready
|
|
|
|
for the requested operation.
|
|
|
|
.Fn select
|
|
|
|
and
|
|
|
|
.Fn pselect
|
|
|
|
return the total number of ready descriptors in all the sets.
|
|
|
|
.Pp
|
|
|
|
The descriptor sets are stored as bit fields in arrays of integers.
|
|
|
|
The following macros are provided for manipulating such descriptor sets:
|
|
|
|
.Fn FD_ZERO fdset
|
|
|
|
initializes a descriptor set pointed to by
|
|
|
|
.Fa fdset
|
|
|
|
to the null set.
|
|
|
|
.Fn FD_SET fd fdset
|
|
|
|
includes a particular descriptor
|
|
|
|
.Fa fd
|
|
|
|
in
|
|
|
|
.Fa fdset .
|
|
|
|
.Fn FD_CLR fd fdset
|
|
|
|
removes
|
|
|
|
.Fa fd
|
|
|
|
from
|
|
|
|
.Fa fdset .
|
|
|
|
.Fn FD_ISSET fd fdset
|
|
|
|
is non-zero if
|
|
|
|
.Fa fd
|
|
|
|
is a member of
|
|
|
|
.Fa fdset ,
|
|
|
|
zero otherwise.
|
|
|
|
The behavior of these macros is undefined if
|
|
|
|
a descriptor value is less than zero or greater than or equal to
|
|
|
|
.Dv FD_SETSIZE ,
|
|
|
|
which is normally at least equal
|
|
|
|
to the maximum number of descriptors supported by the system.
|
|
|
|
.Pp
|
|
|
|
If
|
|
|
|
.Fa timeout
|
|
|
|
is a non-null pointer, it specifies a maximum interval to wait for the
|
|
|
|
selection to complete.
|
|
|
|
If
|
|
|
|
.Fa timeout
|
|
|
|
is a null pointer, the select blocks indefinitely.
|
|
|
|
To poll without blocking, the
|
|
|
|
.Fa timeout
|
|
|
|
argument should be non-null, pointing to a zero-valued timeval or timespec
|
|
|
|
structure, as appropriate.
|
|
|
|
.Fa timeout
|
|
|
|
is not changed by
|
|
|
|
.Fn select ,
|
|
|
|
and may be reused on subsequent calls; however, it is good style to
|
|
|
|
re-initialize it before each invocation of
|
|
|
|
.Fn select .
|
|
|
|
.Pp
|
|
|
|
If
|
|
|
|
.Fa sigmask
|
|
|
|
is a non-null pointer, then the
|
|
|
|
.Fn pselect
|
|
|
|
function shall replace the signal mask of the caller by the set of
|
|
|
|
signals pointed to by
|
|
|
|
.Fa sigmask
|
|
|
|
before examining the descriptors, and shall restore the signal mask
|
|
|
|
of the calling thread before returning.
|
|
|
|
.Pp
|
|
|
|
Any of
|
|
|
|
.Fa readfds ,
|
|
|
|
.Fa writefds ,
|
|
|
|
and
|
|
|
|
.Fa exceptfds
|
|
|
|
may be given as null pointers if no descriptors are of interest.
|
|
|
|
.Sh NOTES
|
|
|
|
It is recommended to use the
|
|
|
|
.Xr poll 2
|
|
|
|
interface instead, which tends to be more portable and efficient.
|
|
|
|
.Sh RETURN VALUES
|
|
|
|
.Fn select
|
|
|
|
returns the number of ready descriptors that are contained in
|
|
|
|
the descriptor sets,
|
|
|
|
or \-1 if an error occurred.
|
|
|
|
If the time limit expires,
|
|
|
|
.Fn select
|
|
|
|
returns 0.
|
|
|
|
If
|
|
|
|
.Fn select
|
|
|
|
returns with an error,
|
|
|
|
including one due to an interrupted call,
|
|
|
|
the descriptor sets will be unmodified.
|
|
|
|
.Sh EXAMPLES
|
|
|
|
.Bd -literal
|
|
|
|
#include \*[Lt]stdio.h\*[Gt]
|
|
|
|
#include \*[Lt]stdlib.h\*[Gt]
|
|
|
|
#include \*[Lt]unistd.h\*[Gt]
|
|
|
|
#include \*[Lt]string.h\*[Gt]
|
|
|
|
#include \*[Lt]err.h\*[Gt]
|
|
|
|
#include \*[Lt]errno.h\*[Gt]
|
|
|
|
#include \*[Lt]sys/types.h\*[Gt]
|
|
|
|
#include \*[Lt]sys/time.h\*[Gt]
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
fd_set read_set;
|
|
|
|
struct timeval timeout;
|
|
|
|
int ret, fd, i;
|
|
|
|
|
|
|
|
/* file descriptor 1 is stdout */
|
|
|
|
fd = 1;
|
|
|
|
|
|
|
|
/* Wait for ten seconds. */
|
|
|
|
timeout.tv_sec = 10;
|
|
|
|
timeout.tv_usec = 0;
|
|
|
|
|
|
|
|
/* Initialize the read set to null */
|
|
|
|
FD_ZERO(\*[Am]read_set);
|
|
|
|
|
|
|
|
/* Add file descriptor 1 to read_set */
|
|
|
|
FD_SET(fd, \*[Am]read_set);
|
|
|
|
|
|
|
|
/*
|
2013-12-06 12:04:52 +01:00
|
|
|
* Check if data is ready to be read on
|
2011-02-14 20:36:03 +01:00
|
|
|
* file descriptor 1, give up after 10 seconds.
|
|
|
|
*/
|
|
|
|
ret = select(fd + 1, \*[Am]read_set, NULL, NULL, \*[Am]timeout);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Returned value is the number of file
|
|
|
|
* descriptors ready for I/O, or -1 on error.
|
|
|
|
*/
|
|
|
|
switch (ret) {
|
|
|
|
case \-1:
|
|
|
|
err(EXIT_FAILURE, "select() failed");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
printf("Timeout, no data received.\en");
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2013-12-06 12:04:52 +01:00
|
|
|
printf("Data received on %d file descriptor(s)\en", ret);
|
2011-02-14 20:36:03 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* select(2) hands back a file descriptor set where
|
|
|
|
* only descriptors ready for I/O are set. These can
|
|
|
|
* be tested using FD_ISSET
|
|
|
|
*/
|
|
|
|
for (i = 0; i \*[Lt]= fd; i++) {
|
|
|
|
if (FD_ISSET(i, \*[Am]read_set)) {
|
|
|
|
printf("Data on file descriptor %d\en", i);
|
|
|
|
/* Remove the file descriptor from the set */
|
|
|
|
FD_CLR(fd, \*[Am]read_set);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
.Ed
|
|
|
|
.Sh ERRORS
|
|
|
|
An error return from
|
|
|
|
.Fn select
|
|
|
|
indicates:
|
|
|
|
.Bl -tag -width Er
|
|
|
|
.It Bq Er EBADF
|
|
|
|
One of the descriptor sets specified an invalid descriptor.
|
|
|
|
.It Bq Er EFAULT
|
|
|
|
One or more of
|
|
|
|
.Fa readfds ,
|
|
|
|
.Fa writefds ,
|
|
|
|
or
|
|
|
|
.Fa exceptfds
|
|
|
|
points outside the process's allocated address space.
|
|
|
|
.It Bq Er EINTR
|
|
|
|
A signal was delivered before the time limit expired and
|
|
|
|
before any of the selected events occurred.
|
|
|
|
.It Bq Er EINVAL
|
|
|
|
The specified time limit is invalid.
|
|
|
|
One of its components is negative or too large.
|
|
|
|
.El
|
|
|
|
.Sh SEE ALSO
|
|
|
|
.Xr accept 2 ,
|
|
|
|
.Xr connect 2 ,
|
|
|
|
.Xr gettimeofday 2 ,
|
|
|
|
.Xr poll 2 ,
|
|
|
|
.Xr read 2 ,
|
|
|
|
.Xr recv 2 ,
|
|
|
|
.Xr send 2 ,
|
|
|
|
.Xr write 2 ,
|
|
|
|
.Xr getdtablesize 3
|
|
|
|
.Sh HISTORY
|
|
|
|
The
|
|
|
|
.Fn select
|
|
|
|
function call appeared in
|
|
|
|
.Bx 4.2 .
|
|
|
|
.Sh BUGS
|
|
|
|
Although the provision of
|
|
|
|
.Xr 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
|
|
|
|
.Ft fd_set
|
|
|
|
is based on the symbol
|
|
|
|
.Dv FD_SETSIZE
|
|
|
|
(currently 256),
|
|
|
|
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
|
|
|
|
.Dv FD_SETSIZE
|
|
|
|
before the inclusion of
|
|
|
|
.In sys/types.h .
|
|
|
|
The kernel will cope, and the userland libraries provided with the
|
|
|
|
system are also ready for large numbers of file descriptors.
|
|
|
|
.Pp
|
|
|
|
Note:
|
|
|
|
.Xr rpc 3
|
|
|
|
library uses
|
|
|
|
.Ft fd_set
|
|
|
|
with the default
|
|
|
|
.Dv FD_SETSIZE
|
|
|
|
as part of its ABI.
|
|
|
|
Therefore, programs that use
|
|
|
|
.Xr rpc 3
|
|
|
|
routines cannot change
|
|
|
|
.Dv FD_SETSIZE .
|
|
|
|
.Pp
|
|
|
|
Alternatively, to be really safe, it is possible to allocate
|
|
|
|
.Ft fd_set
|
|
|
|
bit-arrays dynamically.
|
|
|
|
The idea is to permit a program to work properly even if it is
|
|
|
|
.Xr execve 2 Ns 'd
|
|
|
|
with 4000 file descriptors pre-allocated.
|
|
|
|
The following illustrates the technique which is used by
|
|
|
|
userland libraries:
|
|
|
|
.Pp
|
|
|
|
.Bd -literal -offset indent -compact
|
|
|
|
fd_set *fdsr;
|
|
|
|
int max = fd;
|
|
|
|
|
|
|
|
fdsr = (fd_set *)calloc(howmany(max+1, NFDBITS),
|
|
|
|
sizeof(fd_mask));
|
|
|
|
if (fdsr == NULL) {
|
|
|
|
...
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
FD_SET(fd, fdsr);
|
|
|
|
n = select(max+1, fdsr, NULL, NULL, \*[Am]tv);
|
|
|
|
...
|
|
|
|
free(fdsr);
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
.Fn 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
|
|
|
|
non-conforming systems, it is unwise to assume that the timeout
|
|
|
|
value will be unmodified by the
|
|
|
|
.Fn select
|
|
|
|
call, and the caller should reinitialize it on each invocation.
|
|
|
|
Calculating the delta is easily done by calling
|
|
|
|
.Xr gettimeofday 2
|
|
|
|
before and after the call to
|
|
|
|
.Fn select ,
|
|
|
|
and using
|
|
|
|
.Fn timersub
|
|
|
|
(as described in
|
|
|
|
.Xr getitimer 2 ) .
|
|
|
|
.Pp
|
|
|
|
Internally to the kernel,
|
|
|
|
.Fn select
|
|
|
|
works poorly if multiple processes wait on the same file descriptor.
|