Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

fclose on a non existant file

Status
Not open for further replies.

davetoulouse

Programmer
Jan 12, 2011
3
0
0
FR
Hi All
Sorry this question is paranoid - but i am!
Since this routine will be deep in the code I want it bomb proof ( even Me proof )

As part of a bigger project I have written a trivial
routine to close a file. There is other stuff in it but I reduced it to minimum to verify where problem is.
so:
Code:
#include<stdio.h>
#include<stdlib.h>

int CloseFile(FILE *fp)
{
  if(fclose(fp)!=0)
  {
    return(-1);         
  }
  return(0);
}

This works perfectly well except if I deliberately mess it up.
If I call CloseFile twice
The first call will work and close the file.:)
The second call (where the file is already closed)causes
glibc to be very unhappy with me.Program aborts and fires out a little dump. :(

I know my program should not call this twice
I have programmed it so it will not
BUT
my paranoia says "assume I mess up" ( I am good at messing up ) so trap the error before it happens.

I have looked everywhere i can think of and cannot find a way to do so ( or am missing it )

Can I test to see if "fp" is actualy alive so I can avoid trying to close it if it is not.

if so how?

not sure if important but:
using
gcc verion 4.4.3
make version 3.81

Many Thanks in advance
Dave

 
Alas, it's impossible. The C Standard:
The value of a pointer to a FILE object is
indeterminate after the associated file is closed (including the standard text streams).

Opaque FILE object is not accessible via FILE pointer after fclose (pointer to FILE). If you try to access this memory via "closed" FILE* pointer then your program behaviour is undefined. In other words fclose(fp) where fp points to closed file is the same thing as free(p) where p is deallocated (i.e. points to nowhere).

It seems your CloseFile function is incorrect (it does not check fp == NULL condition) and useless (accept my condolences)...
 
What you can do is check for fp == NULL before closing the file, and set fp = NULL when you do the fclose. This way you won't try to close it twice.
 
Strictly speaking, fp = 0 after fclose is an illusory solution. For example:
Code:
void f(FILE* fp)
{
... fclose(fp); fp = NULL; ...
}
...
f(fp);
if (fp != 0) {
   fclose(fp);
   /* Oops! fp != 0 here but the stream was closed! */
}
 
Hi
Thanks for the replies
I did try setting fp to NULL after a close
and then checking for null before the next close

This may work if they are in line however with my call where it seems to have no effect - it isnt setting fp to Null in the calling routine so if the calling routine calls again it still has the old invalid reference.Maybe some fancy pointer usage is needed.

I guess I will have to step my paranoia down one level.

I am not sure If I am reading correctly but is there doubt
about.
Code:
if(fclose(fp)!=0) 
{
 .... my file mas not closed do something
}
If thats so I risk leaving a lot of junk around and will, if errors occur run out of file handling slots ( there must be a limit )
I am opening and closing lots of files in sequence 500,000 of them in my last test run.I have not seen an issue but am I walking into a trap.


 
Try this instead:
(This is tested to work on my compiler, anyway)
Code:
//---------------------------------------------------------------------------
#include <stdio.h>

int CloseFile(FILE **fp)
{
  if (*fp)
  {
    fclose(*fp);
    *fp = 0;
    return(0);
  }
};

int main(int argc, char* argv[])
{
FILE *FP;
  FP = fopen("Some file","w+");
  CloseFile(&FP);
  CloseFile(&FP);
  return 0;
}
As you will see, this sets the file pointer to null and prevents any further fclose on the closed file, as long as you use the CloseFile function ONLY to close the file.
 
>... if(fclose(fp)!=0) ...

You may try to follow this way if your program has suicidal propensities (the program behavior is undefined in that case).

There is NO portable way to inspect or to change the current stream status via closed FILE pointer (fp points to nowhere). After fclose fp is not a valid argument for stream i/o functions.

After all the C is low-level language (that's OK but what's a wonderful thing - file stream destructor in C++;). Now you have some kind of resourse leaks (remember file stream buffers, for example). Better try to correct this INCORRECT program, don't waste a time for hopeless attempts to get round the C language rules...
 
Thank you all very much,
I appreciate and agree with comments about good practice.
But
I will be doing lots of opeming and closing of files and
this routine will be buried many levels deep and for me personally I like to have a "what cannot happen just happened" warrning.

Thank you Prattarat - your method does well for me.
I Finished with
Code:
int CloseFile(FILE **fp,char *FileName)
{
  if (*fp)  
    {
      if(fflush(*fp)!=0)
      {
          .. ISSUE MINOR WARNING on closing FileName THEN CONTINUE
      }
      if(fclose(*fp)!=0)
      {
          .. ISSUE SERIOUS WARNING on closing FileName THEN BAIL OUT
          *fp=0;        // Just incase I am really stupid
          return(-1);   // calling routine needs to act
      }
      *fp = 0;
      return(0);
    }
    // I should never get here 
          .. ISSUE DAVID IS AN IDIOT WARNING
    return(-1);
};

This seems to work well
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top