"temporarily" redirecting stdin

Chris Torek chris at mimsy.umd.edu
Fri Dec 15 08:28:59 AEST 1989


In article <1989Dec14.185745.7465 at relay.nswc.navy.mil>
dpaulso at relay.nswc.navy.mil (Dave Paulson) writes:
>	stdin_save = dup(fileno(stdin));  /* stdin_save is an int */
>	freopen("config.file","r",stdin); /* connect stdin to the config file*/
>	yyparse();			  /* works ok, input comes from file */
>	close(fileno(stdin));		  /* free stdin descriptor */
>	dup(stdin_save);		  /* restore old stdin */
>	
>this doesn't work.  after the second dup(), reading stdin results
>in EOF.  what have i overlooked?

A great deal.

This sort of `playing around behind stdio's back' is a bad idea.  You
can get it to work in one, two, or perhaps even a dozen implementations,
but there will always be a rogue out there that does things differently.

The best thing to do is note that lex reads not from stdin, but from
yyin, which is initialised to stdin as

	FILE *yyin = stdin, *yyout = stdout;

hence to read `config.file', simply say

	extern FILE *yyin;
	yyin = fopen("config.file", "r");
	if (yyin == NULL) {
		complain, etc.
		exit(1); /* or whatever */
	} else {
		(void) yyparse();	/* do we care if it accepts? */
		(void) fclose(yyin);	/* what do we do on error here?? */
	}

This is much safer than fooling with dup/close/dup sequences.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.unix.questions mailing list