freopen/fread/popen bug

Ken Brown kbrown@cornell.edu
Fri Feb 27 16:17:00 GMT 2015


On 2/27/2015 3:43 AM, Corinna Vinschen wrote:
> On Feb 26 22:05, Ken Brown wrote:
>> I'm not sure exactly where the bug is, but here's what happens (STC at the end):
>>
>> 1. I use freopen to open a file "foo" and associate it with stdin.
>>
>> 2. I use fread to read a byte from foo.
>>
>> 3. I call popen, expecting the child process to have foo as its stdin, with
>> the file-position indicator pointing to the second byte.  But instead the
>> child sees an empty stdin.
>>
>> If I omit step 2, the child process does indeed have foo as its stdin.  Are
>> my expectations wrong, or is this a bug?
>
> Wrong expectations.  Keep in mind that the default read mode using
> stdio functions is buffered.  So your fread fills the buffer in f.
> The buffer is typically something like 1K or 4K.  If the file is
> shorter than that, the file pointer will be set to EOF when calling
> popen.  Try this before calling fread:
>
>    setvbuf(f, NULL, _IONBF, 0);

In the actual code that I'm debugging (part of texinfo), I think that would 
create an unacceptable performance penalty for the child process.

What's really happening is that we need to peek at the first few bytes of f 
before deciding which program to call in popen.  After peeking, there's a call 
to fseek(f,0,0) before the popen, with the intention that the child receives a 
file pointer set to the beginning of the file.  (I left this out of my STC 
because it didn't affect the outcome.)  This apparently works on Linux.

But maybe the problem could be solved by doing a second freopen after peeking.

Ken

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple



More information about the Cygwin mailing list