COHERENT manpages
This page displays the COHERENT manpage for select() [Check if devices are ready for activity].
List of available manpages
Index
select() -- General Function (libsocket)
Check if devices are ready for activity
#include <sys/types.h>
#include <sys/time.h>
#include <sys/select.h>
#include <unistd.h>
int select(nfds, readfds, writefds, exceptfds, timeout)
int nfds;
fd_set *readfds, *writefds, *exceptfds;
struct timeval *timeout;
The function select() examines file descriptors, and tells you which are
ready for a given type of activity. select() can be used with descriptors
for sockets, pipes, and most character devices including the console,
serial terminals connected via the asy driver, and pseudoterminals using
the pty driver.
readfds, writefds, and exceptfds each gives the address of a a bit-map
whose bits correspond to the file descriptors of the sockets that interest
you. Respectively, these arguments identify the sockets that may have data
to be read, those that to which you wish to write data, and those that may
have an exception condition pending. (What an ``error condition'' may be,
is described below.) select() examines descriptors zero through nfds in
each set and checks whether the corresponding socket is ready for the
activity in question. If the socket is not ready, select() flips off the
bits that correspond to that socket.
Please note that although readfds, writefds, and exceptfds each is pointer
to int, the bit-map it points to can be longer than 32 bits. You can, for
example, declare that these pointers points to an array of ints. The number
of file descriptors you can ask select() to examine limited by the manifest
constant FD_SETSIZE, which is defined in header file <sys/select.h>.
COHERENT sets this constant to 256; thus, if you set nfds to a value
greater than 256, only the first 256 file descriptors will be examined.
If you are not interested in a given activity, set the corresponding
pointer to NULL. For example, if you are interested only in reading and
writing, but not in exception handling, set exceptfds to NULL.
timeout gives the address a timeval structure that holds the maximum time
you are willing to wait for the selection to complete. If it is NULL,
select() waits indefinitely.
By manipulating the value of timeout, you can perform some useful tricks.
For example, if you set to zero the fields tv_sec and tv_usec within the
timeval structure to which timeout points, select() performs a nonblocking
poll of the indicated devices; this is demonstrated below. Another trick
is to set field tv_usec within timeout to a nonzero value, but set nfds to
zero. This tells select() to examine no sockets, but to wait the specified
number of microseconds while not doing it. This lets you ``sleep'' for an
interval shorter than is possible through the system call sleep(), whose
minimum delay is one second.
If all goes well, select() returns the number of sockets that are ready.
If the time limit expires, it returns zero. If an error occurs, it leaves
all three bit maps unmodified, returns -1, and sets errno to one of the
following values:
EBADF
A descriptor set specifies an invalid descriptor. For example, this
error occurs if one of the file descriptors does not describes an
ordinary file instead of a socket.
EINTR
select() received a signal before the time limit expired and before it
could finish examining the sockets.
EINVAL
The time structure to which timeout points contains invalid data: one
of its components is negative or too large.
The following example code demonstrates how to set up a socket and examine
it with select(). is taken from a program written by Jon Dhuse
(jdhuse@sedona.intel.com), and was slightly modified for clarity. The
entire program appears in the Lexicon entry libsocket:
int sd[2], rdfds[2], wrtfds[2], i;
struct timeval timeout;
...
/* create socket */
sd = socket(AF_UNIX, SOCK_STREAM, 0);
...
/* initialize the arrays of ints */
for (i = 1; i < 2; i++)
rdfs[i] = 0;
wrtfds[i] = 0;
}
...
/* Check whether socket is ready */
rdfds[0] = 1 << sd; /* initialize bit map to check for reading */
wrtfds[0] = 1 << sd; /* initialize bit map to check for writing */
timeout.tv_sec = 0;
timeout.tv_usec = 0;
i = select(sd+1, rdfds, wrtfds, (int *)NULL, &timeout);
if (i < 0)
printf("select() returned error %d\n", errno);
else {
if (rdfds & (1 << sd)) /* check if socket has data */
printf("socket has data to be read\n");
if (wrtfds & (1 << sd)) /* check if socket can be written to */
printf("data can be written to socket\n");
}
Associated Macros
The header file <sys/select.h> defines the following macros, which
are meant to help you manipulate sets of file descriptors:
FD_ZERO (&fdset)
Initialize the bit map fdset to zero.
FD_SET (fd, &fdset)
Turn on bit fd within the bit map fdset.
FD_CLR (fd, &fdset)
Turn off bit fd within the bit map fdset.
FD_ISSET (fd, fdset)
This macro evaluates to a non-zero value if bit fd is turned on within
fdset; otherwise, it evaluates to zero.
The behavior of these macros is undefined if a descriptor's value is less
than zero or greater than or equal to FD_SETSIZE.
Exception Conditions
As noted above, the bit map exceptfds identifies sockets that may have an
exception condition pending. As of this writing, COHERENT defines an
``exception condition'' to be one of the following:
POLLHUP
A hangup has occurred, i.e., loss of carrier on a modem line or
closure of the associated master device when select() queries a slave
pseudo-tty.
POLLNVAL
The file descriptor does not correspond to an open device.
See Also
accept(),
connect(),
libsocket,
poll(),
read(),
write()
Notes
The system call poll() uses a different calling sequence to do much the
same work as socket().







