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().