views:

66

answers:

2

so if I do:

dup2(0, backup); // backup stdin
dup2(somefile, 0); // somefile has four lines of content
fgets(...stdin); // consume one line
fgets(....stdin); // consume two lines
dup2(backup, 0); // switch stdin back to keyboard

I am finding at this point.. stdin still contains the two lines I haven't consumed. Why is that? Because there is just one buffer no matter how many times you redirect? How do I get rid of the two lines left but still remember where I was in the somefile stream when I want to go back to it?

A: 
dup2(0, backup); // backup stdin 
dup2(somefile, 0); // somefile has four lines of content 
fgets(...stdin); // consume one line 
fgets(....stdin); // consume two lines 
dup2(backup, 0); // switch stdin back to keyboard
BobTurbo
First line should be `backup=dup(0);`. Otherwise you'll encounter all sorts of nasty bugs (not to mention race conditions with threads!) if another file gets opened and happend to get assigned the same fd as `backup`.
R..
+5  A: 

You haven't flushed the stdin buffer. It has buffered up all the lines of somefile even if the underlying file descriptor is restored.

Richard Pennington
dang... beat me to it by a second. :) +1
roe
Yeah, well, I have setbuf to NULL now... anyway, tell me, does stdin have a buffer and whenever you redirect to another stream, it takes what is in that stream and adds it to its buffer and keeps it there even if you redirect to somewhere else again?
BobTurbo
Yes stdio stuff has buffers for file data by default. The file descriptors that dup2(), etc. use aren't buffered at all at the user level. Unfortunately (for you ;-), the file descriptor calls don't know about the upper level stdio calls and don't do anything to make sure the stdio buffers stay in sync when you change file descriptors under their nose.
Richard Pennington