How to tell a file is been close.

E

empriser

FILE *fp;

fp = fopen( ... )
fclose( fp ).


How do I know if fp has been fclose.
I know can set fp to NULL after fclose it, then check fp's value to
solve the problem.
But, if there have other methods?
 
R

Richard Heathfield

empriser said:
FILE *fp;

fp = fopen( ... )
fclose( fp ).

fclose can fail. Check the return result. (Here, I'm speaking as much to
myself as to you!)

How do I know if fp has been fclose.
I know can set fp to NULL after fclose it, then check fp's value to
solve the problem.

Right. When you call fclose, the value of fp becomes indeterminate,
which means that you are no longer allowed to use that value for any
purpose. So the best thing you can do is give fp a new value that you
/can/ use, and NULL is the obvious candidate.

But, if there have other methods?

No.
 
C

Chris Dollin

empriser said:
FILE *fp;

fp = fopen( ... )
fclose( fp ).


How do I know if fp has been fclose.

You have to remember that you've closed it. (Or, preferably,
arrange that you don't have to care.)
I know can set fp to NULL after fclose it, then check fp's value to
solve the problem.

That doesn't help if there are other copies of `fp`s value.

A useful trick is to arrange that your file-handling code looks like:

{ FILE* fp = fopenSuitably()
; doThingsWithFile( fp )
; fclose( fp )
; }

(Don't mind my layout, I'm being experimental today.)

(Insert check on `fclose` working to taste.)

Now, this piece of code is so short it's easy to check that
you never use `fp` after its been closed. (Assuming that
`doThingsWithFile` doesn't wilfully copy `fp` elsewhere.)

And sometimes you can arrange that `doThingsWithFile` is a
function pointer. (If it needs extra state, pass that in too.)

If most of your file-handling can be done that way, you only need
to be deeply suspicious of other uses of files.

Another trick is to have a struct

struct fileAndBoolean
{ YourBooleanType closed
; FILE* fp
; }

Write file-accessing methods on `struct fileAndBoolean*`. Have them
check whether `closed` is true. Set `closed` on `close()`.

Whether these tricks are of value to you depends on your context.
 
T

Tor Rustad

empriser said:
FILE *fp;

fp = fopen( ... )
fclose( fp ).


How do I know if fp has been fclose.

fclose() returns 0 on success.
I know can set fp to NULL after fclose it, then check fp's value to
solve the problem.

what is the problem?
 
C

christian.bau

fclose can fail. Check the return result. (Here, I'm speaking as much to
myself as to you!)

The question is: If it fails, what are you supposed to do? fclose can
obviously fail if I make some programming error, like fclose (fp);
fclose (fp); where the second call is quite likely to fail. But apart
from that, what can you do?
 
Q

quarkLore

The question is: If it fails, what are you supposed to do? fclose can
obviously fail if I make some programming error, like fclose (fp);
fclose (fp); where the second call is quite likely to fail. But apart
from that, what can you do?

Error propagation and catching is a problem in C and in general
structured programming languages.
Coming back to the topic. You can check the errno. Check this:
http://man.he.net/?topic=fclose&section=all

Check this to know how to use errno: http://www.mkssoftware.com/docs/man5/errno.5.asp
http://www.unix.geek.org.uk/~arny/info/library_2.html
 
R

Richard Tobin

fclose can fail. Check the return result. (Here, I'm speaking as much to
myself as to you!)
[/QUOTE]
The question is: If it fails, what are you supposed to do? fclose can
obviously fail if I make some programming error, like fclose (fp);
fclose (fp); where the second call is quite likely to fail. But apart
from that, what can you do?

You can warn the user, so he doesn't delete the old version of his
data.

-- Richard
 
W

William Ahern

Tor Rustad said:
fclose() returns 0 on success.

Even on failure fp is still effectively closed for all intents and purposes.
fp becomes (or remains) invalid either way.
 
R

Richard Heathfield

christian.bau said:
The question is: If it fails, what are you supposed to do? fclose can
obviously fail if I make some programming error, like fclose (fp);
fclose (fp); where the second call is quite likely to fail. But apart
from that, what can you do?

As Richard T points out, you can warn the user. Also, you may still have
the data in memory, in which case you can prompt for a different
filename, suggesting to the user that he might like to specify a
different device.

"Warn the user" is the very least you can do for /any/ failure (except
one). Often you can do more, but even if you can't, at least you can
clue the user in to what is going wrong.

The one exception, of course, is where the failure is that your program
can't write to the output device that your user is monitoring (be it
stderr or some customised dialog routine or whatever). Some days, it
just isn't worth getting out of bed.
 
R

Richard Tobin

Richard Heathfield said:
"Warn the user" is the very least you can do for /any/ failure (except
one). Often you can do more, but even if you can't, at least you can
clue the user in to what is going wrong.

The one exception, of course, is where the failure is that your program
can't write to the output device that your user is monitoring (be it
stderr or some customised dialog routine or whatever). Some days, it
just isn't worth getting out of bed.

You could sit in a loop, so that the user has to kill the program.
That should make them think twice about checking the data is intact.

-- Richard
 
T

Tor Rustad

William said:
Even on failure fp is still effectively closed for all intents and purposes.
fp becomes (or remains) invalid either way.

fclose(NULL);

close nothing.
 
M

Mark McIntyre

The question is: If it fails, what are you supposed to do? fclose can
obviously fail if I make some programming error, like fclose (fp);
fclose (fp); where the second call is quite likely to fail. But apart
from that, what can you do?

Depends why it failed. Could be tht the OS can't flush the buffers to
disk because there's no space at present, or it could be the
filehandle got corrupted, etc etc. Solutions would differ, and you'd
need to check other information to determine how to respond.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
T

Tor Rustad

christian.bau said:
The question is: If it fails, what are you supposed to do? fclose can
obviously fail if I make some programming error, like fclose (fp);
fclose (fp); where the second call is quite likely to fail. But apart
from that, what can you do?

What type of program and system do you have in mind?

If we ignore trivial case of an invalid stream pointer on input,
typically a write to file failure has caused your fclose() error.

A very simplistic recovery, would be to retry the operation on the file,
but that is a gamble, possibly the file is already in a corrupted state
and further write to it, would only do more harm. On Linux EFBIG, it is
rather pointless to retry..

So, it depend on the error value set in errno, e.g. Linux EFAULT is bad,
your program is possibly in an undefined state, and the best thing to do
is usually exit ASAP.

Making programs fault tolerant is a complex topic, if I really don't
need that, I follow the "worse is better" design

http://www.jwz.org/doc/worse-is-better.html

and just log error to the system log and exit.
 
A

Al Balmer

The question is: If it fails, what are you supposed to do? fclose can
obviously fail if I make some programming error, like fclose (fp);
fclose (fp); where the second call is quite likely to fail. But apart
from that, what can you do?

Notify the user, probably. Other than that, possible action depends on
why the call failed, and both the reasons and the error codes are
implementation dependent.
 
K

Keith Thompson

quarkLore said:
Error propagation and catching is a problem in C and in general
structured programming languages.
Coming back to the topic. You can check the errno.

Yes, but the C standard doesn't say that fclose() sets errno on
failure (though many implementations do so).

Set errno to 0 before the call, and check its value after the call
*only* if fclose() reported an error by returning EOF. (fclose()
returns 0 on success, EOF on error.)

Based on a quick glance, that looks like good information, but some of
it is system-specific, and it doesn't mention the need to set errno to
0 before a call.

Consider a system where a given function *doesn't* set errno. Before
the call, it could have any arbitrary value from some previous error.
If the call fails without setting errno, you could end up using bogus
information.
 
K

Keith Thompson

Tor Rustad said:
fclose(NULL);

close nothing.

I'm not sure what your point is, but fclose(NULL) invokes undefined
behavior. fclose "causes the stream pointed to by stream to be
flushed and the associated file to be closed"; if there is no such
stream, the behavior is undefined by omission.
 
B

B. Augestad

Keith said:
I'm not sure what your point is, but fclose(NULL) invokes undefined
behavior. fclose "causes the stream pointed to by stream to be
flushed and the associated file to be closed"; if there is no such
stream, the behavior is undefined by omission.

I was puzzled by Tors post too. Some investigation reveals that the man
page for fclose() on Cygwin confirms this. Here's what it says:

`fclose' returns `0' if successful (including when FP is `NULL'
or not an open file); otherwise, it returns `EOF'.

So on such systems fclose(NULL) seems to be fine. Even
FILE *fp = fopen("whatever", "r");
fclose(fp);
fclose(fp);
fclose(fp);
should work on that implementation. A Very Bad Choice, IMO. Why not
stick to the standard?


Bjørn
 
K

Keith Thompson

B. Augestad said:
I was puzzled by Tors post too. Some investigation reveals that the
man page for fclose() on Cygwin confirms this. Here's what it says:

`fclose' returns `0' if successful (including when FP is `NULL'
or not an open file); otherwise, it returns `EOF'.

So on such systems fclose(NULL) seems to be fine. Even
FILE *fp = fopen("whatever", "r");
fclose(fp);
fclose(fp);
fclose(fp);
should work on that implementation. A Very Bad Choice, IMO. Why not
stick to the standard?

I agree that it's a bad choice, but it does stick to the standard.
Returning 0 is perfectly consistent with undefined behavior.

Incidentally, it's not clear to me from the standard whether

FILE *fp = fopen("whatever", "r"); /* assume success */
fclose(fp);
fclose(fp);

invokes undefined behavior or not. C99 7.19.5.1 says that "the stream
is disassociated from the file", but it doesn't say that the stream no
longer exists after that.

I think one could argue that the second fclose() must succeed, or that
it must fail, or that it invokes undefined behavior. (Or maybe it's
just too early in the morning.)
 
R

Richard Tobin

Keith Thompson said:
Incidentally, it's not clear to me from the standard whether

FILE *fp = fopen("whatever", "r"); /* assume success */
fclose(fp);
fclose(fp);

invokes undefined behavior or not.

I'm not going to work through the standard right now, but this has to
be undefined behaviour. Otherwise FILE objects couldn't be re-used,
which they are in many implementations (and were even before C89).

Consider:

FILE *fp1 = fopen("whatever1", "r"); /* assume success */
fclose(fp1);
FILE *fp2 = fopen("whatever2", "r"); /* assume success */

In many implementations fp1 and fp2 are equal (yes, in theory it's
probably undefined behaviour to compare them). Calling fclose(fp1)
again at the end will close the second file.

-- 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

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top