Take the 2-minute tour ×

When sockets are created or files are opened/created in C, is the file descriptor that's assigned to the socket/file guaranteed to be the lowest-valued descriptor available? What does the C spec say about file descriptor assignment in this regard, if anything?

share|improve this question

6 Answers 6

up vote 4 down vote accepted

It's not guaranteed to be the lowest, and is implementation dependent (1). In general, however, the routine that assigns open file descriptors uses a method that gives you the first open on. It could be that immediately after several lower ones free, leaving you with a higher descriptor than you might expect though.

The only reason I can think of to know this, though, is for the select function, which is sped up if you pass it the highest file descriptor you need to check for.

(1) Note that those implementations that follow the IEEE standard do guarantee the lowest unused descriptor for files, but this may not apply to sockets. Not every implementation follows the IEEE standard for open(), so if you're writing portable software it is best not to depend on it.

share|improve this answer
Calling open() is guaranteed to return the lowest available file descriptor: opengroup.org/onlinepubs/009695399/functions/open.html There appears to be no such guarantee for sockets. –  Ville Laurikari May 22 '09 at 17:14
Thanks for the reminder and specific reference! –  Adam Davis May 26 '09 at 17:49
"The IEEE standard" being referred to is POSIX. It would be worthwhile to mention this... –  R.. Aug 7 '10 at 15:05

I don't think you'll find it in the C spec, more likely the spec for your OS. My experience in Linux has been that it's always the lowest.

share|improve this answer

I'll counter this with another question - why does this matter? You shouldn't be comparing the file descriptor with anything (unless checking for stdin/stdout/stderr) or doing math with it. As long as it fits in an int (and its guaranteed to) that's all you really need to know.

share|improve this answer
Not true. Using it with select requires it to fit into an fd_set object. And since POSIX requires file descriptors to be allocated sequentially, you might similarly want to use your own bit-array objects for storing sets of file descriptors, which you can do portably. –  R.. Aug 7 '10 at 15:07

Steve M is right; C has no notion of sockets, and its file I/O functions use a [pointer to a] FILE object, not a descriptor.

share|improve this answer
C actually has two ways of reading files, one with the FILE object and one with the file descriptor. –  Kyle Cronin Sep 9 '08 at 11:31
The file descriptor based way is the system call interface provided by the Unix API, not part of C proper. –  wnoise Sep 21 '08 at 20:58

@aib the open(), close(), lseek(), read(), write() all make use of file descriptors. I hardly ever use streams for I/O.

@Kyle it matters because of statements like select(). Knowing the highest descriptor can improve performance.

share|improve this answer

The C spec says that it's implementation dependent. If you're looking at a Unix implementation, the man page for open(2) says "The file descriptor returned by a successful call will be the lowest-numbered file descriptor not currently open for the process."

This helps if you're trying to attach a specific file to a specific descriptor. Say you want to redirect stderr to /dev/null. Something like

close(2); open("/dev/null", O_WRONLY);

ought to do it. You should, of course, capture the fd returned by open and ensure that it's 2.

share|improve this answer
Or, use dup2 to ensure you assign the correct stream to the intended file descriptor. –  LnxPrgr3 Dec 17 '09 at 21:04
If your program uses threads and you don't have tight control over what the other threads are doing, dup2 is the only safe way. close/open introduces a race condition, during which another thread may get the file descriptor. –  R.. Aug 7 '10 at 15:08

Your Answer

