fclose return value check
From comp.lang.c:
The fclose() call can fail, and should be error-checked just as assiduously as all the other file operations. Sounds pedantic, right? Wrong. In a former life, my company's product managed to destroy a customer's data by omitting a check for failure when closing a file. The sequence went something like (paraphrased):
stream = fopen(tempfile, "w"); if (stream == NULL) ... while (more_to_write) if (fwrite(buffer, 1, buflen, stream) != buflen) ... fclose (stream); /* The new version has been written successfully. Delete * the old one and rename. */ remove (realfile); rename (tempfile, realfile);
Of course, what happened was that fclose() ran out of disk space trying to write the last couple blocks of data, so the `tempfile' was truncated and unusable. And since the fclose() failure wasn't detected, the program went right ahead and destroyed the best extant version of the data in favor of the damaged version. And, as Murphy would have it, the victim in this particular incident was the person in charge of the customer's department, the person with authority to buy more of our product or replace it with a competitor's product -- and, natch, a person who was already unhappy with us for other reasons.
It'd be a stretch to ascribe all of the ensuing misery to this single omission, but it may be worth pointing out that both the customer and my former company have since vanished from the corporate ecology.
CHECK THOSE FAILURE CODES!
When you fwrite
to a file, it may not actually write anything, it may stay in a buffer (inside the FILE object). Calling fflush
would actually write it to disk. That operation may fail, for example if you just ran out of disk space, or there is some other I/O error.
fclose
flushes the buffers implicitly too, so it may fail for the same reasons.
You could (and should) report the error, but in a sense, the stream is still closed:
After the call to fclose(), any use of stream results in undefined behavior.
fclose()
will flush any unwritten output (viafflush()
) before returning, so the error results from the underlyingwrite()
won't be reported atfwrite()
orfprintf()
time, but when you do thefclose()
. As a result, any error thatwrite()
orfflush()
can generate can be generated byfclose()
.fclose()
will also callclose()
which can generate errors on NFS clients, where the changed file isn't actually uploaded to the remote server untilclose()
time. If the NFS server crashed, then theclose()
will fail, and thusfclose()
will fail as well. This might be true of other networked filesystems.