Stream buffering and flushing behaviour

Marc-André Lureau marcandre.lureau@gmail.com
Tue Jul 7 15:39:00 GMT 2015


Hi

I am wondering how best to solve the following:

#include <stdio.h>
#include <assert.h>

void main()
{
    FILE *f;
    char foo[4096];
    int n;

    f = fopen("/tmp/test", "a+"); /* qemu does fdopen */
    assert(f);
    fwrite("Hello World!\n", 1, 13, f);

    n = fread(foo, 1, READ_SIZE, f);
    fprintf(stderr, "eof?%d %d", feof(f), n);

    fseek(f, 0, SEEK_SET);
    n = fread(foo, 1, sizeof(foo), f);
    fprintf(stderr, "eof?%d %d", feof(f), n);
}

with READ_SIZE >= 4096, there is no implicit flush taking place, while
with READ_SIZE < 4096 (13 for ex), it does flush to disk and
subsequent read after seek will return the expected buffer.

According to glibc manual
http://www.gnu.org/software/libc/manual/html_mono/libc.html#Flushing-Buffers,
flushing should happen "
Whenever an input operation on any stream actually reads data from its
file.", but in the case the requested buffer is too large, you can see
it doesn't. I am a bit dubious about what best to do to have the
second read "correct". Should the program track the read/write mode
and when switching, do an explicit fflush()?

thanks a lot for your help

(fwiw, this is related to the following qemu-ga bug
https://bugzilla.redhat.com/show_bug.cgi?id=1210246)



-- 
Marc-André Lureau



More information about the Libc-help mailing list