1332 Chapter 63
These macros operate as follows:
z FD_ZERO() initializes the set pointed to by fdset to be empty.
z FD_SET() adds the file descriptor fd to the set pointed to by fdset.
z FD_CLR() removes the file descriptor fd from the set pointed to by fdset.
z FD_ISSET() returns true if the file descriptor fd is a member of the set pointed to
by fdset.
A file descriptor set has a maximum size, defined by the constant FD_SETSIZE. On
Linux, this constant has the value 1024. (Other UNIX implementations have similar
values for this limit.)
Even though the FD_* macros are operating on user-space data structures, and
the kernel implementation of select() can handle descriptor sets with larger
sizes, glibc provides no simple way of modifying the definition of FD_SETSIZE. If
we want to change this limit, we must modify the definition in the glibc header
files. However, for reasons that we describe later in this chapter, if we need to
monitor large numbers of descriptors, then using epoll is probably preferable
to the use of select().
The readfds, writefds, and exceptfds arguments are all value-result. Before the call to
select(), the fd_set structures pointed to by these arguments must be initialized
(using FD_ZERO() and FD_SET()) to contain the set of file descriptors of interest. The
select() call modifies each of these structures so that, on return, they contain the set
of file descriptors that are ready. (Since these structures are modified by the call,
we must ensure that we reinitialize them if we are repeatedly calling select() from
within a loop.) The structures can then be examined using FD_ISSET().
If we are not interested in a particular class of events, then the corresponding
fd_set argument can be specified as NULL. We say more about the precise meaning of
each of the three event types in Section 63.2.3.
The nfds argument must be set one greater than the highest file descriptor
number included in any of the three file descriptor sets. This argument allows
select() to be more efficient, since the kernel then knows not to check whether file
descriptor numbers higher than this value are part of each file descriptor set.
#include <sys/select.h>
void FD_ZERO(fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_CLR(int fd, fd_set *fdset);
int FD_ISSET(int fd, fd_set *fdset);
Returns true (1) if fd is in fdset, or false (0) otherwise