Richard Morgan
Richard Morgan

Reputation: 7691

Why is calling close() after fopen() not closing?

I ran across the following code in one of our in-house dlls and I am trying to understand the behavior it was showing:

long GetFD(long* fd, const char* fileName, const char* mode)
{
    string fileMode;

    if (strlen(mode) == 0 || tolower(mode[0]) == 'w' || tolower(mode[0]) == 'o')
        fileMode = string("w");
    else if (tolower(mode[0]) == 'a')
        fileMode = string("a");
    else if (tolower(mode[0]) == 'r')
        fileMode = string("r");
    else
        return -1;

    FILE* ofp;
    ofp = fopen(fileName, fileMode.c_str());
    if (! ofp)
        return -1;

    *fd = (long)_fileno(ofp);
    if (*fd < 0)
        return -1;

    return 0;
}

long CloseFD(long fd)
{
    close((int)fd);
    return 0;
}

After repeated calling of GetFD with the appropriate CloseFD, the whole dll would no longer be able to do any file IO. I wrote a tester program and found that I could GetFD 509 times, but the 510th time would error.

Using Process Explorer, the number of Handles did not increase.

So it seems that the dll is reaching the limit for the number of open files; setting _setmaxstdio(2048) does increase the amount of times we can call GetFD. Obviously, the close() is working quite right.

After a bit of searching, I replaced the fopen() call with:

long GetFD(long* fd, const char* fileName, const char* mode)
{
    *fd = (long)open(fileName, 2);
    if (*fd < 0)
      return -1; 

    return 0;
}

Now, repeatedly calling GetFD/CloseFD works.

What is going on here?

Upvotes: 4

Views: 6272

Answers (5)

sam
sam

Reputation: 376

you are open the file fopen() function so u have to close the file useing fclose(), if you are using open() function and try to call fclose() function it will not work

Upvotes: 2

jeff7
jeff7

Reputation: 2182

fopen opens it's own file descriptor, so you'd need to do an fclose(ofp) in your original function to prevent running out of file descriptors. Usually, one either uses the lower level file descriptor functions open, close OR the buffered fopen, fclose functions.

Upvotes: 3

dave4420
dave4420

Reputation: 47052

The standard library you are using has a static array of FILE structures. Because you are not calling fclose(), the standard library doesn't know that the underlying files have been closed, so it doesn't know it can reuse the corresponding FILE structures. You get an error after it has run out of entries in the FILE array.

Upvotes: 5

Paul R
Paul R

Reputation: 213029

You need to use fclose with files opened via fopen, or close with files opened via open.

Upvotes: 8

Vlad
Vlad

Reputation: 35594

If you open a file with fopen, you have to close it with fclose, symmetrically.

The C++ runtime must be given a chance to clean up/deallocate its inner file-related structures.

Upvotes: 17

Related Questions