select |
Prototype: |
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int hi_fd, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
FD_CLR(int fd, fd_set *set);
FD_ISSET(int fd, fd_set *set);
FD_SET(int fd, fd_set *set);
FD_ZERO(fd_set *set);
|
General Description: |
Wait for any I/O status changes from the file descriptor sets. When any of the specified sets changes, the call returns. You have four macros to help construct and manage the file descriptor sets: FD_CLR - Remove a descriptor from the set. FD_SET - Add a descriptor to a set. FD_ISSET - Test if specified descriptor is ready for I/O. FD_ZERO - Initialize the set to empty. |
Return Value: |
The number of descriptors that have changed states. If an error occurred, the return value is negative. If the timeout expired, the return value is zero. |
Parameters |
hi_fd |
This is the highest file descriptor number +1. So if you have four files open, plus the stdio, your descriptors could be [0,1,2,3,5,6,8]. The highest is 8. So, if you include fd(8) in your select statement, hi_fd would equal 9. However, if the highest fd was 5, this parameter would be 6. |
readfds |
The set of descriptors to test for readability. |
writefds |
The set of descriptors to test for writing. |
exceptfds |
The set of descriptors to test for out-of-band data. |
timeout |
The maximum time to wait for data to arrive in microseconds. This is a pointer to a number. If the number is a zero (not the pointer), the call returns immediately after checking all the descriptors. If the pointer is NULL (zero), the select's timeout feature is disabled. |
fd |
The file descriptor to add, remove or test. |
set |
The file descriptor set. |
Possible Errors |
EBADF |
An invalid file descriptor was given in one of the sets. |
EINTR |
A non blocked signal was caught. |
EINVAL |
n is negative. |
ENOMEM |
select was unable to allocate memory for internal tables. |
Examples |
int i, ports[]={9001, 9002, 9004, -1};
int sockfd, max=0;
fd_set set;
struct sockaddr_in addr;
struct timeval timeout={2,500000}; /* 2.5 sec. */
FD_ZERO(&set);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
for ( i = 0; ports[i] > 0; i++ )
{
sockfd = socket(PF_INET, SOCK_STREAM, 0);
addr.sin_port = htons(ports[i]);
if ( bind(sockfd, &addr, sizeof(addr)) != 0)
perror("bind() failed");
else
{
FD_SET(sockfd, &set);
if ( max < sockfd )
max = sockfd;
}
}
if ( select(max+1, &set, 0, &set, &timeout) > 0 )
{
for ( i = 0; i <= max; i++ )
if ( FD_ISSET(i, &set) )
{ int client = accept(i, 0, 0);
/**** process the client's requests ****/
}
}
|