A
Alan Balmer
Sorry for not repeating the entire post. It was in reference to theChapter and verse, please.
Dan
preceding post, which was implementation specific, and clearly
indicated as such.
Sorry for not repeating the entire post. It was in reference to theChapter and verse, please.
Dan
It happened in perfectly ordinary "Unixy" code on Sun workstations
using NFS servers, even with all the hardware working perfectly.
Files written to the server would be write-behind cached on the
workstations. On the final fflush()-before-close, the last data
would be transferred from the user process to the client workstation
kernel. The kernel continued to cache the data, not sending any
of it to the NFS server yet.
On the close(), the workstation would realize that it was now
time to send the cached data to the server, which would reject
the write with EDQUOT, "user is over quota".
The close() would return the EDQUOT error to the user process,
alerting the user that his file was incomplete because he was
now out of administrator-assigned disk space.
All fflush can tell you is that the data has successfully left the
stdio buffers. It may still be bufferred by the OS. Only fclose can
confirm that it successfully reached its final destination.
Even if it's not recoverable, the user still needs to be informed about
the problem. As it is impossible to predict the consequences of a
failed fclose, it is unacceptable to ignore this possibility.
In said:How does fclose confirm that? The description of fclose in this
respect is identical to that of fflush: "Any unwritten buffered data
for the stream are delivered to the host environment to be written to
the file;"
That doesn't mean that catching the problem *before* closing the file
is a bad thing, does it?
fclose() does more than fflush().
2 A successful call to the fclose function causes the stream
pointed to by stream to be flushed and the associated file to be
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
closed.
^^^^^^
This is what allows fclose to detect what fflush may not be able to
detect. Closing the associated file implies flushing all the buffers
associated to that file, even those stdio (and, implicitly, fflush) has
no control upon.
Chris said:(snip)
It happened in perfectly ordinary "Unixy" code on Sun workstations
using NFS servers, even with all the hardware working perfectly.
Files written to the server would be write-behind cached on the
workstations. On the final fflush()-before-close, the last data
would be transferred from the user process to the client workstation
kernel. The kernel continued to cache the data, not sending any
of it to the NFS server yet.
On the close(), the workstation would realize that it was now
time to send the cached data to the server, which would reject
the write with EDQUOT, "user is over quota".
The close() would return the EDQUOT error to the user process,
alerting the user that his file was incomplete because he was
now out of administrator-assigned disk space.
(This kind of failure generally came as a total shock to the users,
whose programs completely ignored the close() failure and often
followed the failed close() by a rename() operation that wiped
out the original backup file. Now they had plenty of disk space
for the data, but no data to go in it.)
In said:Sorry, I don't see that. It certainly implies that the file is no
longer associated with the calling program, but I don't know what
prevents the implementation from caching the actual final writes,
directory updates, etc. until it finds a propitious moment.
There may
even be more than one system involved, as in the case of a
network-connected file.
If it's delayed, an error may happen when the closing is actually
attempted and there is no way to report it to the fclose() caller.
While the standard says that a successful fclose call cause the file
to be closed.
(snip)
I'm not claiming that each and every implementation actually does what
the standard requires, merely that the requirement is written in
unambiguous terms.
I'm sorry, but I can't find an alternate interpretation for "closing the
associated file", no matter where it is physically located and how many
systems are involved in actually performing this action.
In said:That's the point of my concerns - I can't find (in the standard) *any*
interpretation of "closing the associated file." I don't see that the
standard can require any particular action by the system, any more
than it can guarantee that another process doesn't have the same file
open.
If it's opened for input only, you couldn't/shouldn't care less.
Stephen Howe said:Being pedantic, you should check every return value of every call of all
functions in <stdio.h> even if opened for input only.
Christopher said:I doubt you check the return value of printf - if you do, I'm glad I
don't have to read your code...
Eric Sosman said:#include <stdio.h>
int main(void) {
if (printf("Hello, world!\n") != 14) {
if (fprintf(stderr, "printf failed!\n") != 15) {
if (fprintf(stderr, "fprintf failed!\n") != 16) {
...
Christopher said:I doubt you check the return value of printf - if you do, I'm glad
I don't have to read your code...
#include <stdio.h>
#include <stdlib.h>
int main(void) {
if (printf("Hello, world!\n") != 14) {
if (fprintf(stderr, "printf failed!\n") != 15) {
if (fprintf(stderr, "fprintf failed!\n") != 16) {
exit(EXIT_FAILURE);
if (fprintf(stderr,
"exit(EXIT_FAILURE) failed!!\n") != 28) {
abort();
if (fprintf(stderr, "abort() failed!!\n") != 17) {
/* ... */
}
}
}
}
}
exit(EXIT_SUCCESS);
if (fprintf(stderr, "exit(EXIT_SUCCESS) failed!!\n") != 28) {
abort();
if (fprintf(stderr, "abort() failed!!\n") != 17) {
/* ... */
}
}
}
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.