testing fclose...really necessary

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

Is it really necessary to check the return type (int) or fclose ? fopen
I can understand but what about using

fflsuh(fp); /* fopen's pointer */
fclose(fp);

Would that take care of any unforseen truncation ?

Bill
 
D

Default User

Eric Sosman wrote:

Gad, that was an awful experience! I wound up flying to St. Louis
to try to placate the irate customer by allowing him to rip my face
off with a cheese grater -- well, perhaps I exaggerate, but my day in
St. Louis remains in memory as one of the most unpleasant of my
working life.


My fair city now tarnished in your memory. Like getting sick after
eating some food at a kid.




Brian
 
K

Keith Thompson

Bill Cunningham said:
Is it really necessary to check the return type (int) or fclose ? fopen
I can understand but what about using

fflsuh(fp); /* fopen's pointer */

Typo: fflush(fp);
fclose(fp);

Would that take care of any unforseen truncation ?

No. fflush can fail as easily as fclose can; you should check the
result of both calls (though it's common not to bother checking the
result of fflush(stdout)).

If you've been writing to a stream (fp, stdout, whatever), it can have
buffered data that hasn't yet been written to the physical file (your
screen, foo.dat, whatever). Either flushing or closing the stream
will cause the system to *attempt* to write out any buffered data, or
at least to pass it on to another part of the system that will
eventually write it to the physical media. In either case, that can
fail for any number of reasons: the disk might be full, you might have
unplugged something, etc.

When writing to stdout or stderr, it's fairly common to omit checks,
since (a) any failure will often be fairly obvious to the user, and
(b) there's not much you can do to recover (where do you write the
error message?). For anything else, you should always check the
result of every I/O operation, even if all you do in the event of
failure is to abort the program with an error message.

(*Sometimes* it might be better to atttempt to continue running after
an error, but you're not writing anything where that would apply.)
 
R

Richard Tobin

Keith Thompson said:
If you've been writing to a stream (fp, stdout, whatever), it can have
buffered data that hasn't yet been written to the physical file (your
screen, foo.dat, whatever). Either flushing or closing the stream
will cause the system to *attempt* to write out any buffered data, or
at least to pass it on to another part of the system that will
eventually write it to the physical media. In either case, that can
fail for any number of reasons: the disk might be full, you might have
unplugged something, etc.

fflush() may well succeed even though the data has not yet reached its
destination. fclose() on the other hand should not return until
the lower levels have reported success. Write failures can be caused
by common things like full filesystems, and the failure may not be
immediate for a networked fileserver.
When writing to stdout or stderr, it's fairly common to omit checks,
since (a) any failure will often be fairly obvious to the user, and
(b) there's not much you can do to recover (where do you write the
error message?).

You may not be able to recover, but you can avoid taking some
destructive action like deleting the input file.
For anything else, you should always check the
result of every I/O operation, even if all you do in the event of
failure is to abort the program with an error message.

Or check ferror() at the end of a loop, if it's tedious to check every
operation. But don't do this for infinite, or even very lengthy,
loops.

-- Richard
 
B

Bill Cunningham

fflush() may well succeed even though the data has not yet reached its
destination. fclose() on the other hand should not return until
the lower levels have reported success. Write failures can be caused
by common things like full filesystems, and the failure may not be
immediate for a networked fileserver.

I see.

Bill
 
K

Keith Thompson

fflush() may well succeed even though the data has not yet reached its
destination. fclose() on the other hand should not return until
the lower levels have reported success. Write failures can be caused
by common things like full filesystems, and the failure may not be
immediate for a networked fileserver.

That's not guaranteed, and it may not always be possible. In fact,
the standard uses the same wording for both fclose and fflush.

C99 7.19.5.1 (fclose):

Any unwritten buffered data for the stream are delivered to the
host environment to be written to the file; any unread buffered
data are discarded.

C99 7.19.5.2 (fflush):

If stream points to an output stream or an update stream in which
the most recent operation was not input, the fflush function
causes any unwritten data for that stream to be delivered to the
host environment to be written to the file; otherwise, the
behavior is undefined.
You may not be able to recover, but you can avoid taking some
destructive action like deleting the input file.

Ideally, yes.

What I should have said is that such checks are often omitted for
programs where stdout and stderr are normally expected to be written
to an interactive device.
 
R

Richard Tobin

fflush() may well succeed even though the data has not yet reached its
destination. fclose() on the other hand should not return until
the lower levels have reported success. Write failures can be caused
by common things like full filesystems, and the failure may not be
immediate for a networked fileserver.
[/QUOTE]
That's not guaranteed, and it may not always be possible. In fact,
the standard uses the same wording for both fclose and fflush.

True, but in practice fclose() is likely to call close() or its
equivalent, which is likely to do the right thing.

This was a real problem when NFS first came along: programs didn't
check the result of fclose() (or close(), if they used it directly),
and editors would delete old versions even though writing the new one
had failed.

-- Richard
 
K

Keith Thompson

That's not guaranteed, and it may not always be possible. In fact,
the standard uses the same wording for both fclose and fflush.

True, but in practice fclose() is likely to call close() or its
equivalent, which is likely to do the right thing.[/QUOTE]

Isn't fflush equally likely to do the right thing?
This was a real problem when NFS first came along: programs didn't
check the result of fclose() (or close(), if they used it directly),
and editors would delete old versions even though writing the new one
had failed.

Perhaps, but the conclusion is the same in either case: always check
the result of both fflush and fclose.
 
R

Richard Tobin

True, but in practice fclose() is likely to call close() or its
equivalent, which is likely to do the right thing.
[/QUOTE]
Isn't fflush equally likely to do the right thing?

Fflush() is just likely to call write() or equivalent, and check the
result. So it won't see any delayed errors which would be detected
by fclose().

-- Richard
 
R

Richard Bos

Robert Gamble said:
Eric Sosman posted a compelling example of what can go wrong when you
don't check the return value of fclose() a while back, you can read it
at <http://groups.google.com/group/comp.lang.c/msg/c601c3fd60dd536a>.

I used to think checking fclose() was unnecessary, but Eric's example
convinced me otherwise; however, do note that it's only true for _write_
streams. I still can't think of an overwhelming reason to check fclose()
for read streams.

Richard
 
K

Keith Thompson

I used to think checking fclose() was unnecessary, but Eric's example
convinced me otherwise; however, do note that it's only true for _write_
streams. I still can't think of an overwhelming reason to check fclose()
for read streams.

Hmm.

I suppose that fclose on a read stream is very unlikely to fail, since
it doesn't do much. But if it *does* fail, it's likely to indicate
some serious problem with the system, something that you might to know
about. Then again, it's likely to be something that's not relevant to
your program, so there's a good chance it can be safely ignored.
 
R

Richard Bos

Keith Thompson said:
Hmm.

I suppose that fclose on a read stream is very unlikely to fail, since
it doesn't do much. But if it *does* fail, it's likely to indicate
some serious problem with the system, something that you might to know
about. Then again, it's likely to be something that's not relevant to
your program, so there's a good chance it can be safely ignored.

Such problems (and such error messages) are likely to be of interest to
a systems administrator, but not to a normal user. This could be a
reason to check fclose() for read streams only in systems software, not
in (say) a word processor.

Richard
 

Ask a Question

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.

Ask a Question

Similar Threads

URGENT 1
error 28
fseek 17
code 34
fopen 17
Deleting first N lines from a text file 26
A little rusty on pointers to pointers 1
why is it dumping core? 19

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top