I have the following toy code to test out I/O buffering on fread
, and I'm getting results that I didn't expect:
#include <stdio.h>
#include <stdio_ext.h>
int main()
{
FILE *fp;
char buff[255];
fp = fopen("/home/install.sh", "r");
int result = setvbuf(fp, NULL, _IOFBF, 700); // set buffering size to some arbitrary value, say 700
printf("Result of setting buffer: %d\n", result ); // "Result of setting buffer: 0"
printf("Buffer size: %zd\n", __fbufsize(fp) ); // "Buffer size: 4096"
fread(buff, 255, 1, fp);
printf("%s\n", buff ); // prints 255 bytes as I would expect
}
From above, it seems like the setvbuf
call was successful as it returned 0
, however the buffer size stays at 4096
. Moreover, I tried printing out BUFSIZ
and it says 8192
. Running strace
does show the underlying read
call as being 4096
bytes. Turning off buffering seems to work fine, as buffer size gets set to 1.
Moreover, I don't understand why BUFSIZ
(8192
) is not the same as the default value of these reads (4096
).
I tried many different values for the buffer size but to no avail.
I am running ldd (Ubuntu GLIBC 2.27-3ubuntu1) 2.27
setvbuf not changing buffer size?
Glibc setvbuf implementation just ignores the size
argument when mode == _IOFBF
and buff == NULL
. Which is fine - characteristics of buffering modes are implementation defined. And __fbufsize
is a nonstandard extensions. Generally you shouldn't depend on the buffering of the underlying FILE
.
I don't understand why BUFSIZ (8192) is not the same as the default value of these reads (4096).
Glibc
does mmap the file. Because of mmap
the size get's rounded to page size.