Why would fopen fail to open a file that exists?
Asked Answered
D

5

6

I'm on Windows XP using Visual Studio 6 (yes I know it's old) building/maintaining a C++ DLL. I'm encountered a problem with fopen failing to open an existing file, it always returns NULL.

I've tried:

  • Checking errno and _doserrno by setting both to zero and then checking them again, both remain zero, and thus GetLastError() reports no errors. I know fopen isn't required to set errno when it encounters an error according to a C standard.
  • Hardcoding the file path, which are not relative.
  • Tried on another developers machine which the same result.

The really strange thing is CreateFile works and the file can be read with ReadFile. We believe this works in a release build, however we are also seeing some very odd behaviour in other areas of the application and we're not sure if this is related.

The code is below, I don't see anything odd it looks quite standard to me. The source file hasn't changed for just under half a year.

HRESULT CDataHandler::LoadFile( CStdString szFilePath )
{
    //Code
    FILE* pFile;
    if ( NULL == ( pFile = fopen( szFilePath.c_str(), "rb") ) )
    {
        return S_FALSE;
    }
    //More code
}
Deliberation answered 14/1, 2011 at 10:19 Comment(8)
Visual C++ 6 is not really C++. Certainly tagging both C and C++ is nonsensical. Decide on a language, both in your tags and in your code.Towne
Oh, and as for the question, check that you have permission to access the file. It doesn't just have to exist: your program has to be able to access it.Towne
@Tomalak: Yeah, we get it, VC++ 6.0 is not standards-compliant. But it's confusing to tell people it's not C++ when it very clearly claims to be. It's certainly not C, so what's the alternative? I completely agree that tagging both C and C++ is nonsensical.Vanpelt
@CodyGray: It's not C++. It is non-compliant (as you say) in too many ways to be accurately or responsibly referred to as C++. It's a C++-like language. I appreciate that this might seem dramatic, but it is a big distinction when you're helping someone on code that has been advertised as C++ but really is not subject to the same laws.Towne
fopen does not have the security attribute semantics that the Windows requires.Garland
This laboured point about C++ compliance of VC6 is completely irrelevant to a question which is actually about a call to the C standard library, albeit one made from C++ (or whatever Tomalak thinks we should call the language which the VC6 C++ compiler compiles)Aesthetics
If for whatever reason, you need to be able to open more than 512 files, you can increase that using the _setmaxstdio function. See the documentation. (Also, you should post "The Answer" as an actual answer, rather than as part of your question, and then accept it by clicking the checkmark in the left margin.)Vanpelt
The application doesn't need that many files open. It was simply a mismatching fopen and fclose.Deliberation
D
10

The Answer:

I found the cause, too many open file handles cause by some recent updates to the application. These where not code changes though so this bug has been present for a while. I stepped into the fopen function down to a function called _getstream. This attempts to find a stream not in use, the function searches a table of 512 streams Sure enough all 512 where in use and other calls to fopen where failing. I used the handle tool from sysinternals to see the number of used handles.

Deliberation answered 14/1, 2011 at 12:5 Comment(0)
S
2

Your function has an HRESULT return type (where 0 is good) but you return a boolean (where 0 is bad). That can't be right...

Sickly answered 14/1, 2011 at 10:47 Comment(1)
My mistake, should have been S_FALSE.Deliberation
A
1

Assuming you have a reasonable version of VC6, then you have the source code to the CRT, and you can step into the fopen call, and all the way down to the CreateFile call that the CRT will make. (Be prepared for it to be quite a long way down!)

Aesthetics answered 14/1, 2011 at 10:47 Comment(1)
I found the CRT sources of the installation disk and stepped into fopen. Luckily I didn't have to step too far down to discover the cause. (See original question)Deliberation
B
1

put breakpoint on fopen line, trigger it in debugger, input "ERR, hr" in "Watch" window, execute the line and check in Watch what was the problem. Most probably it's access permissions.

Boone answered 14/1, 2011 at 11:33 Comment(1)
I've never heard of putting ERR into the watch window, but this worked perfectly for me. Thank you!Pantelleria
A
0

You are already having 512 opened files.

We can hold only max 512 opened files in VC application. I am suggesting to close the unnecessary files using fclose.

Awry answered 23/4, 2014 at 12:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.