Last Updated: 12-Nov-08
We want to make a Unix system call select() and proceed only when
#include <sys/select.h> #include <sys/time.h> #include <errno.h> ... fd_set rset, wset; // Declare the descriptor sets int maxfdp; struct timeval timeout; int retval; for (;;) { /* Clear the descriptor sets */ FD_ZERO(&rset); // Clear all bits FD_ZERO(&wset); /* The descriptor sets */ FD_SET(fd_read1, &rset); // Set the bit FD_SET(fd_read2, &rset); ... FD_SET(fd_write1, &wset); ... // FD_CLR(fd, &wset); // Clear the bit for fd ... maxfdp = fd_read1; if (fd_read2 > maxfdp) maxfdp = fd_read2; ... /* Timeout: 2.3 seconds */ /* Always set 'timeout' before select() since it might have been updated by the previous select() call * The select() of some Unix systems (such as Linux) updates the 'timeout' argument to indicate how * much time was left. (POSIX.1-2001 does not enforce but permits this behavior.) */ timeout.tv_sec = 2; // seconds timeout.tv_usec = 300000; // microseconds; 1 microsecond = 1E-6 second retval = select(maxfdp + 1, &rset, // Ready for reading? Can be NULL. &wset, // Ready for writing? Can be NULL. NULL, // Have an exception condition pending? Can be NULL. &timeout // NULL for not setting the timeout ); if (retval > 0) { // Positive counts of ready descriptors if (FD_ISSET(fd_read1, &rset)) { // fd_read1 is readable ... } if (FD_ISSET(fd_read2, &rset)) { // fd_read2 is readable ... } if (FD_ISSET(fd_write1, &wset)) { // fd_write1 is writable ... } ... // NEVER check the file descriptors not included in the sets for select(), // or you may get Segmentation Fault. ... } else if (retval == 0) { // Timeout ... } else { // retval < 0 // Error. Can refer to errno for the exact reason. if (errno == EINTR) { // The call was interrupted as a signal was caught. Should retry. } ... } } ...