freopen/fread/popen bug

Corinna Vinschen corinna-cygwin@cygwin.com
Fri Feb 27 16:21:00 GMT 2015


On Feb 27 07:40, Ken Brown wrote:
> 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.

This is non-portable.  If the seek operation can be performed within the
bytes already in the stream buffer, then fseek is not required to call
lseek.

This is an old discussion in how far the state of streams has to be
adjusted when calling execve and what a child process may expect.  There
are two ways to handle it and two schools of thought, so there's no
right or wrong.

The only portable way to get what you want with fully buffered streams
is to call fflush() on the streams before calling fork/exec (which is
what popen is, basically).


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20150227/f8e308ed/attachment.sig>


More information about the Cygwin mailing list