From man select :
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
nfds should be set to the highest-numbered file descriptor in any of the three sets, plus 1.
I'm quite curious about :
- Why
plus 1is needed, not highest-numbered file descriptor itself? - Why request
plus 1operation in user input, instead of handling it inside the system?
From sys_generic.c, it seems related __NFDBITS, but I'm not able to go further.
static int max_select_fd(unsigned long n, fd_set_bits *fds)
339{
340 unsigned long *open_fds;
341 unsigned long set;
342 int max;
343 struct fdtable *fdt;
344
345 /* handle last in-complete long-word first */
346 set = ~(~0UL << (n & (__NFDBITS-1)));
347 n /= __NFDBITS;
348 fdt = files_fdtable(current->files);
349 open_fds = fdt->open_fds->fds_bits+n;
350 max = 0;
351 if (set) {
352 set &= BITS(fds, n);
353 if (set) {
354 if (!(set & ~*open_fds))
355 goto get_max;
356 return -EBADF;
357 }
358 }
359 while (n) {
360 open_fds--;
361 n--;
362 set = BITS(fds, n);
Similar topic but not the same:
What's the purpose of the first argument to select system call?