Bug with fread() in CentOS 8
Posted
Introduction
I discovered a bug the other day in some old C code which appeared when the code started running on CentOS 8. I thought it was worth writing about because the same code had no issue when running on CentOS 7.
Note that this issue really has nothing to do with CentOS. It just so happens
that the glibc
version changed from 2.17 to 2.28 when moving from CentOS 7 to
CentOS 8.
Bug Description
The crux of the issue is that in the CentOS 7 glibc
version, a call to
fread
will return data regardless of whether the “end of file” flag is set on
a FILE*
variable. In newer glibc
versions, a call fread
will not return
data unless the “end of file” flag is cleared with clearerr
.
There’s not anything wrong with the new behavior, but the change can introduce subtle bugs for code which relied on the old behavior.
Example Code
I’ve written an example program which demonstrates this issue.
The test program accepts an input argument which determines whether or not the
program will mitigate the bug. If the argument is true
, the bug will occur.
If the argument is false
, the bug will be mitigated by calling clearerr
between the two fread
calls.
CentOS 7 Output
$ ./test true
Reading - n_read is 6 data is "HELLO " feof is true
Reading - n_read is 5 data is "HELLO WORLD" feof is true
$ ./test false
Reading - n_read is 6 data is "HELLO " feof is true
Reading - n_read is 5 data is "HELLO WORLD" feof is true
CentOS 8 Output
$ ./test true
Reading - n_read is 6 data is "HELLO " feof is true
Reading - n_read is 0 data is "HELLO " feof is true
$ ./test false
Reading - n_read is 6 data is "HELLO " feof is true
Reading - n_read is 5 data is "HELLO WORLD" feof is true