Many people who try to use select() come across behavior that is difficult to understand and
produces nonportable or borderline results. For instance, the above program is carefully
written not to block at any point, even though it does not set its file descriptors to non-
blocking mode. It is easy to introduce subtle errors that will remove the advantage of using
select(), so here is a list of essentials to watch for when using select().
1. You should always try to use select() without a timeout. Your program should have noth-
ing to do if there is no data available. Code that depends on timeouts is not usually
portable and is difficult to debug.
2. The value nfds must be properly calculated for efficiency as explained above.
3. No file descriptor must be added to any set if you do not intend to check its result
after the select() call, and respond appropriately. See next rule.
4. After select() returns, all file descriptors in all sets should be checked to see if they
5. The functions read(2), recv(2), write(2), and send(2) do not necessarily read/write the
full amount of data that you have requested. If they do read/write the full amount, it's
because you have a low traffic load and a fast stream. This is not always going to be
the case. You should cope with the case of your functions only managing to send or
receive a single byte.
6. Never read/write only in single bytes at a time unless you are really sure that you have
a small amount of data to process. It is extremely inefficient not to read/write as much
data as you can buffer each time. The buffers in the example below are 1024 bytes
although they could easily be made larger.
7. The functions read(2), recv(2), write(2), and send(2) as well as the select() call can
return -1 with errno set to EINTR, or with errno set to EAGAIN (EWOULDBLOCK). These
results must be properly managed (not done properly above). If your program is not going
to receive any signals, then it is unlikely you will get EINTR. If your program does not
set nonblocking I/O, you will not get EAGAIN.
8. Never call read(2), recv(2), write(2), or send(2) with a buffer length of zero.
9. If the functions read(2), recv(2), write(2), and send(2) fail with errors other than
those listed in 7., or one of the input functions returns 0, indicating end of file, then
you should not pass that descriptor to select() again. In the example below, I close the
descriptor immediately, and then set it to -1 to prevent it being included in a set.
10. The timeout value must be initialized with each new call to select(), since some operat-
ing systems modify the structure. pselect() however does not modify its timeout struc-
11. Since select() modifies its file descriptor sets, if the call is being used in a loop,
then the sets must be reinitialized before each call.