Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would fopen fail to open a file that exists?

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
}
like image 405
void Avatar asked Jan 14 '11 10:01

void


Video Answer


3 Answers

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

like image 20
trojanfoe Avatar answered Sep 22 '22 00:09

trojanfoe


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.

like image 188
void Avatar answered Sep 21 '22 00:09

void


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

like image 38
Will Dean Avatar answered Sep 21 '22 00:09

Will Dean