views:

1651

answers:

3

The prototype is:

int select (int nfds,
            fd_set *read-fds,
            fd_set *write-fds,
            fd_set *except-fds,
            struct timeval *timeout);

I've been struggling to understand this function for quite some time. My question is, if it checks all the file descriptors from 0 to nfds-1, and will modify the read-fds, write-fds and except-fds when return, why do I need to use FD_SET to add file descriptors to the set at the begining, it will check all the file descriptors anyway, or not?

A: 

It won't check from 0 to nfds-1. The first argument just provides an upper bound on how large, numerically, the file descriptors used are. This is because the set itself might be represented as a bitvector, without a way to know how many bits are actually used. Specifying this as a separate argument helps select() avoid checking file descriptors that are not in use.

Also, a descriptor that is not in e.g. the read set when you call select() is not being checked at all, so it cannot appear in the set when the call returns, either.

unwind
A: 

I once had the same doubt as yours. You can look at following question and answers:

http://stackoverflow.com/questions/644370/query-on-select-system-call

Prabhu. S
Thanks, that thread is also very helpful!
gc
A: 

Thanks a lot! You answered it almost right after I asked it! Stackoverflow rocks!

I realize I just didn't read carefully enough, at the same time the explanation from different sources confused me a bit:

the descriptors from 0 through nfds-1 in the descriptor sets are examined

"nfds is the highest-numbered file descriptor in any of the three sets, plus 1" - Linux man page

And it's good to have someone to explain why it is like this! Thank again unwind!

gc