I'm writing a program, some kind of database. While I was reading manual of fclose(3) I found that it calls fflush(3) to flush FILE* buffers to disk (actually to OS buffer, but it doesn't matter right now, we can always call fsync(2)).
Because I'm writing a DB it is obvious that I want to prevent data loss. If there is no disk space and fflush(3) in fclose(3) fails — we will lose our data, because
using
FILE*after an error infclose()will cause undefined behavior
So I thought about explicit use of fflush(3) before fclose(3), warn user about low disk space and recall fflush(3) after a while.
I've read the C standard and thought this was a good idea. In practice, after failed fflush the second call would always return 0 (no error), but would actually do nothing. fsync didn't help me (I thought data might be saved in RAM).
How can I prevent data loss in such a situation? Maybe there are some rules of thumb.
Here is my test code:
#include <stdio.h>
int main()
{
FILE *a = fopen("/tmp/1", "wb")
if ( !a )
perror("fopen");
if ( fwrite("test", 1, 4, a) != 4 )
perror("fwrite"); // always OK, cause data is buffered
while( fflush(a) ) // ...second call will always return 0!
{
perror("fflush"); // if there is no disk space, I will get this perror, but ...
}
if ( fclose(a) ) // always ok, because calls only close(2)
perror("fclose");
return 0;
}