gcc (GCC) 4.7.2
c89
Is it possible for check if a file has already closed?
I have opened a file using fopen()
and closed using fclose(fd)
.
This file gets opened and closed during the running of the program. However, the user can terminate the program by doing a ctrl-c
.
When I go to my cleanup routine, I don't know if the file is in a open or closed state. So if I try and do a fclose(fd)
twice, it will stack dump.
Some ideas I have been throwing around:
- Add a state to the file to be either opened or closed, and then check that state, means more work for such a simple job.
- Don't do anything as the OS will cleanup automatially when the program ends.
- Is there is the access function, but that will just checks the mode.
Many thanks in advance,
Open the file using the "fopen" function and assign the "file" to the variable. Check to make sure the file was successfully opened by checking to see if the variable == NULL. If it does, an error has occured. Use the fprintf or fscanf functions to write/read from the file.
Test whether fopen returns -1 , which indicates that the file open failed. For example: ... fid = fopen(filename, 'r'); if fid == -1 % fopen failed else % fopen successful, okay to call fread A = fread(fid); ...
If the file doesn't exist, a new file is created. Returns NULL, if unable to open the file. The file is opened for reading and appending(writing at end of file).
The open function creates and returns a new file descriptor for the file named by filename . Initially, the file position indicator for the file is at the beginning of the file.
AFAIK, glibc doesn't provide a method to validate a FILE*
variable.
Keeping some kind of state or just setting fd
to NULL
works, but you have to be careful not to get into your cleanup routine just after closing the file, but before resetting fd
. As Ctrl+C sends a signal (SIGINT) to a program, you can just block the signal while the file is being closed and fd is being reset. So, your fclose
in the main program should look like:
// 1. Block SIGINT
sigset_t old_mask, to_block;
sigemptyset(&to_block);
sigaddset(&to_block, SIGINT);
sigprocmask(SIG_BLOCK, &to_block, &old_mask);
// 2. Close the file and reset fd
fclose(fd);
fd = NULL;
// 3. Restore signal handling
sigprocmask(SIG_SETMASK, &old_mask, NULL);
And in your clean-up routine you should just check fd
:
if (fd != NULL) fclose(fd);
If your program is multithreaded, you should use pthread_sigmask
instead.
In your case, simple call of fcloseall()
in the cleanup routine would be much easier.
As for the second option meant in your question, about doing nothing - well, the OS will clean-up everything for your program. Then only drawback is that if there were opened write streams, some data may be not written to disk. But maybe in case of Ctrl+C it's just ok.
It seams to me that there is a little confusion in your mind.
File handlers, used with fopen
, fclose
, f...
functions are process scope. I.e., they are valid within application (normally).
Two things can happen when you open a file: you succeed or not. If you succeed, you may be using file exclusively or shared with other processes. If you fail, maybe another process is already using file. Search _fsopen
.
When process ends, normally or interrupted (as with Ctrl+C
), OS releases resources associated with process, sooner or later. This applies to file handlers, memory, ...
Regarding your question, whether your application end normally or with Ctrl+C
, unclosed file handlers will be released by OS.
Whenever your application starts, you need to open file handlers you need. OS will not keep them open for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With