5

I'm writing a server that needs to handle many open sockets, so I use setrlimit() to set the maximum number of open file descriptors (as root, before dropping privileges) like so:

#include <sys/resource.h>
#define MAX_FD_C 9001

if (setrlimit(
      RLIMIT_NOFILE, &(struct rlimit){.rlim_cur = MAX_FD_C, .rlim_max = MAX_FD_C}
    ) == -1) {
    perror("Failed to set the maximum number of open file descriptors");
    return EXIT_FAILURE;
}

Now, I realize there probably won't be any guarantees and that I'm at the mercy of whatever method the Linux kernel uses to implements file descriptor tables; but in practice, is it reasonable to assume that any fd this program receives from the Linux kernel will have a value less than the MAX_FD_C I set above?

I'd like to keep per socket data as compact as possible which could mean simply using an array like static struct client clients[MAX_FD_C] = {{0}}; and using the fd as the index to the client struct (which would basically be my own version of the FDT).

Will
  • 2,014
  • 2
  • 19
  • 42
  • 1
    Yes, file descriptors will be in the range 0 <= fd < max, but I don't have the citations for it. – Dietrich Epp May 18 '13 at 05:07
  • Don't assume anything while programming. It makes you live longer. Seriously. – Randy Howard May 18 '13 at 05:07
  • @RandyHoward: I think assumptions are necessary to keep us sane and efficient. – Dietrich Epp May 18 '13 at 05:10
  • You can assume that the code you will be asked to fix when it isn't working will have been written by somebody originally that made a lot of unwarranted assumptions. ;-) – Randy Howard May 18 '13 at 05:12
  • 1
    Well... at least I came to SO and posted my question here, in order to have my assumptions scrutinized first. Also, I avoid assumptions as much as possible, but in this case *not assuming* would require a larger array, resulting in more cache misses, and noticeably worse performance. All because I'm only 99.9% sure instead of 100%.`Don't assume anything while programming. It makes you live longer.` And taking calculated risks is what makes one successful and live happier? – Will May 18 '13 at 05:18
  • "unwarranted assumptions" -- The OP asked about *reasonable* assumptions. it's your comments that are unwarranted. – Jim Balter May 18 '13 at 07:37

1 Answers1

3

There are functions in the POSIX standard which assume this already. Have a look at FD_SETSIZE, select(), FD_SET.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • I guess it's this from the `select` man page: `An fd_set is a fixed size buffer. Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or larger than FD_SETSIZE will result in undefined behavior. Moreover, POSIX requires fd to be a valid file descriptor.`? – Will May 18 '13 at 05:37
  • @Will: Note that this doesn't guarantee that you can't ever get a file descriptor above `FD_SETSIZE`, but `open` does guarantee the resulting file descriptor is "a small integer" and other things break when they aren't small. If you like, you can also use `dup2` to move out-of-range fds into range (pick an unused entry, obviously). – Ben Voigt May 18 '13 at 05:44
  • 1
    Thanks to your reply I noticed the following sentence in the man page for `open`: `The open() function shall return a file descriptor for the named file that is the lowest file descriptor not currently open for that process`. I read this to logically mean that any new fd will be either less than any open fd, or exactly one larger than the largest open fd, which in turn is proof that no fd can ever be larger than the set maximum (because to reach an fd > max, you'd have to have more fds open than the max). Maybe you could add this to your answer (or I could create an answer of myself I guess). – Will May 18 '13 at 06:03
  • Then again, although that applies to `open()` it may not necessarily apply to other functions like `accept()`. Oh well, I guess I'm convinced enough though anyway. – Will May 18 '13 at 06:10
  • @Will: Return values from `socket` and `accept` are also passed to `select`, so they need to follow the same rules. – Ben Voigt May 18 '13 at 15:57