int select(int highestfd,
struct timeval *timeout);
The first parameter is the highest file descriptor listed in all three
sets + 1. Thus, if our process watches 2 file descriptors numbered 0 and
1, highestfd should be 2. The second, third, and forth parameters are
pointers to fd_set -- a data structure containing a set of file
descriptors to watch. Any of these parameters may be NULL. readfds
contains file descriptors from which the process reads data, writefds
contains file descriptors to which the process writes, and exceptfds
contains exception file descriptors (it's usually ignored). Use the
following macros to manipulate these structs easily:
FD_ZERO (fd_set *fds) -- Empties fds.
FD_SET(int fd, fd_set* fds) -- Adds fd to fds.
FD_CLR(int fd, fd_set* fds) -- Removes fd from fds.
FD_ISSET(int fd, fd_set* fds) -- Returns true if fd is contained in
The last parameter indicates how long select() should wait for an event.
If it's NULL, then select() will block until an event occurs.
When select() returns, readfds, writefds, and exceptfds contain the file
descriptors that have input pending, that are ready to be written to,
and that are in an exceptional condition. The return value is the total
number of file descriptors contained in these sets, 0 if the call timed
out or -1 if an error occurred. As select() modifies the sets passed to
it, you should copy them to a different set before each call.
The following program reads from two pipes "p1" and "p2" using select():
int fds; /*file descriptors to watch*/
int i, highestfd;
fd_set readset; /*updated by select*/
fd_set stableset;/*for restoring readset after select()*/
/*open both pipes for read. For the sake of brevity,
runtime errors aren't checked here*/
fds=open("p1", O_RDONLY | O_NONBLOCK);
fds=open("p2", O_RDONLY | O_NONBLOCK);
/*add descriptors to set*/
/*find the max descriptor value*/
highestfd = fds > fds ? fds : fds;
/*as long as at least one descriptor is being watched*/
while (FD_ISSET(fds, &stableset) ||
FD_ISSET(fds, &stableset) )
readset=stableset; /*reconstitute original set*/
if(select(highestfd+1, &readset, NULL, NULL, NULL)<0)
/*handle errors and exit*/
/*loop through files that have input pending*/
for (i=0; i<2; i++)
if FD_ISSET(fds[i], &readset)
read(fds[i], buf, sizeof(buf)-1);