On 02/27/2015 05:40 AM, Ken Brown wrote: >> 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.
How? Whether the parent reads buffered or unbuffered has no impact on the child. > > 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. Corinna is correct - you need to fflush() after the fseek() for it to affect the underlying offset. Or, just use read()/lseek() instead of fread()/fseek() in the parent, to avoid stdio buffering altogether. That way, you'll guarantee the offset the child process will inherit without having to worry about flushing buffered state. > > But maybe the problem could be solved by doing a second freopen after > peeking. Only if freopen() is guaranteed to reset the file position to 0. When using freopen("file"), that is true; but when using freopen(NULL) (for the side effect of changing text/binary mode), it is not guaranteed. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature