File descriptors and streams and copying thereof.

Geoff Clare gwc at root.co.uk
Fri Apr 21 07:56:54 AEST 1989


In article <8450 at xanth.cs.odu.edu> kremer at cs.odu.edu (Lloyd Kremer) writes:
[trimmed down a bit - gwc]
>
>	int insave;
>	insave = dup(fileno(stdin));
>	if(freopen("my_filename", "r", stdin) == (FILE *)0)
>		forget the whole thing;
>	else{
>		do work requiring input redirection;
>		fclose(stdin);
>	}
>	fdopen(dup(insave), "r");
>	/* get a copy of the saved original input file descriptor and
>		associate it with a buffered stdio FILE structure.
>		Again we know the lowest file descriptor and the
>		lowest FILE (_iob[0]) will be returned */
		^^^^^^^^^^^
		* This is a false assumption *
>
>	close(insave);

I don't know where Lloyd got this idea from, but there is nothing in
any standard which guarantees a newly opened FILE will be the lowest
available.  In fact "lowest" may not have any sensible meaning on an
implementation which does not have an "_iob[]" style array of FILE
structures.

So be warned.  Code which relies on this behaviour is not portable.

It is, of course, safe to assume the stream returned by fopen() and
friends has the lowest available file descriptor (i.e. fileno(stream)),
but portable code should not assume that

	fclose(stdin); newstream = fdopen(somefd, "r");

will result in newstream==stdin.

Going back to the original question, temporary redirection of stdin can
be achieved (on UNIX(tm) systems) by a slight modification to the method
for "low-level I/O" which Lloyd gave in his article.

All that is necessary is a fflush(stdin) before any change of
the file associated with fileno(stdin).  This will result in loss
of data already read into the buffer, but the same is true of
Lloyd's proposed method, due to the freopen().

-- 

Geoff Clare    UniSoft Limited, Saunderson House, Hayne Street, London EC1A 9HH
gwc at root.co.uk   ...!mcvax!ukc!root44!gwc   +44-1-315-6600  FAX: +44-1-315-6622



More information about the Comp.lang.c mailing list