unix question about stdin

Guy Harris guy at auspex.auspex.com
Sun Apr 23 22:15:36 AEST 1989


>The original post wanted to know how to reconnect the stdin to the terminal
>after it had been attached to a file, assumedly through redirection.  What I
>just tried on a BSD system, and works:
>
>  fclose(stdin);
>  *stdin = *fopen("/dev/tty", "r");
>
>The "*" before stdin is necessary because of the way stdin is defined in
><stdio.h>.

*Urk* while this may work, I don't think it's *guaranteed* to work.  In
most UNIX standard I/O implementations, a standard I/O stream is
represented by a pointer to an object of type FILE (or of type "struct
_iobuf", which FILE is a #define for).  Said structure can be copied by
assignment; you have to dereference said pointer to do so, which is why
the "*" is needed.

*However*, I don't know whether every standard I/O implementation in the
world would work correctly if you copy one FILE object atop another one.

There's a better way of doing this, namely to declare:

	FILE *input;

and do your reading from "input" rather than "stdin".  This means you
have to use "getc(input)" rather than "getchar()", and the like.  You
first do

	input = stdin;

and all reads from "input" come from the standard input.  You then do

	input = fopen(file, "r");

and - assuming "fopen" doesn't return NULL, due to it being unable to
open "file"; DON'T forget to check for this! - all reads from "input"
will come from the file in question.  Finally, you do

	fclose(file);
	input = stdin;

which will close the file and make all reads from "input" come from the
standard input again.

One advantage of this is that, unlike schemes involving "/dev/tty", it
will work even if you redirect your standad input away from your
terminal; input will come from the file you redirected to, and then from
the file opened by the program, and then go back to the file to which
input was originally redirected.



More information about the Comp.unix.wizards mailing list