Requesting help on intricacies of duplicated file descriptors.

Rich Felker dalias at aerifal.cx
Sun Jul 23 03:35:43 UTC 2006


On Sun, Jul 23, 2006 at 01:07:33AM +0000, Garrett Kajmowicz wrote:
> If I take the following:
> 
> fp = fdopen(fileno(stdin)));
> 
> Can I have stdin in blocking mode and fp in non-blocking mode? 

There are 3 different levels (maybe more but 3 is enough for this
discussion) at which you can think of the properties associated with a
file:

- stdio stream (FILE * object)
- file descriptor
- open file description (or whatever posix calls it, I forget..)

Stdio streams are each associated with a file descriptor and wrap it
with buffering and other functionality. As in your example, there can
be many associated with one fd.

File descriptors are a process resource referring to open files. More
than one may refer to the same "open file description" which is
stronger than referring to the same file; they share the same file
position and properties like the blocking/nonblocking flag. The only
difference between file descriptors referring to the same open file is
that they can independently be set close-on-exec, and some of the file
locking semantics which I don't want to get into.

So to answer your question.. It doesn't quite make sense because "fp"
does not have a nonblocking flag. Rather fileno(stdin) has one, which
both FILE * objects would share since they share the file descriptor.
SUSv3 has a good explanation of the intricacies of using more than one
reference to the same open file, but in general it's a very bad idea
to use more than one FILE * with the same fd. Very bad things
(corruption) can happen if it's a file on disk. The only time it's
useful is when you have a fd that's a tty or similar device open for
both reading and writing, and you want to use separate FILE * objects
for reading and writing to it. (You cannot use one for both because
you cannot switch between read/write without seeking and seek on a tty
does not work.)

Also it's a bad idea to use non-blocking io with stdio streams (FILE
*) unless you really know what you're doing. If no input is available,
the read operation will return with error and set the error flag for
the stream. It can be cleared with fclearerr() and presumably you can
continue reading then, but nonblocking io is really the most useful in
connection with the non-buffering unix-style fd io functions.

Rich




More information about the uClibc mailing list