Stream buffering and flushing behaviour

Carlos O'Donell carlos@redhat.com
Tue Jul 7 19:24:00 GMT 2015


On 07/07/2015 02:43 PM, Marc-André Lureau wrote:
> Hi Carlos
> 
> On Tue, Jul 7, 2015 at 8:23 PM, Carlos O'Donell <carlos@redhat.com> wrote:
>>> 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.
>>
>> Do you mean `fread after fseek`?
> 
> yes
> 
>> I don't see anything. Do you have a test case that shows the problem?
>> Expected and observed results?
> 
> Sorry, the example code is a bit borked, here is a simpler version:
> 
> #include <stdio.h>
> #include <assert.h>
> 
> int main()
> {
>     FILE *f;
>     char foo[4096];
>     int n;
> 
>     f = fopen("/tmp/test", "w+");
>     assert(f);
>     fwrite("Hello World!\n", 1, 13, f);
> 
>     n = fread(foo, 1, FIRST_READ_SIZE, f);
>     assert(n == 0);
> 
>     fseek(f, 0, SEEK_SET);
>     n = fread(foo, 1, sizeof(foo), f);
>     assert(n == 13);
>     return 0;
> }
> 
> Compiled with -DFIRST_READ_SIZE=4096 = fail, -DFIRST_READ_SIZE=13 = pass.

Thanks.

> Is this expected?

No, and it reproduces in upstream master.

I've asked Siddhesh to have a look at it since he
last made changes to this code in upstream master.
While we both have a good understanding of the code,
his understanding is better.

The use of w+, as opposed to a+ in the bugzilla,
certainly simplifies things. The fseek should seek
the pointer within the buffer and return 13 always
regardless of the read size.

Cheers,
Carlos.



More information about the Libc-help mailing list