Better cleanup if PHYSFS_init() fails halfway through.

This commit is contained in:
Ryan C. Gordon 2012-03-25 16:13:23 -04:00
parent 4cfd7277f3
commit 107f07da97
1 changed files with 32 additions and 29 deletions

View File

@ -1132,9 +1132,9 @@ static int initStaticArchivers(void)
assert(staticArchivers[numStaticArchivers - 1] == NULL);
archiveInfo = (const PHYSFS_ArchiveInfo **) allocator.Malloc(len);
GOTO_IF_MACRO(!archiveInfo, PHYSFS_ERR_OUT_OF_MEMORY, failed);
BAIL_IF_MACRO(!archiveInfo, PHYSFS_ERR_OUT_OF_MEMORY, 0);
archivers = (const PHYSFS_Archiver **) allocator.Malloc(len);
GOTO_IF_MACRO(!archivers, PHYSFS_ERR_OUT_OF_MEMORY, failed);
BAIL_IF_MACRO(!archivers, PHYSFS_ERR_OUT_OF_MEMORY, 0);
for (i = 0; i < numStaticArchivers - 1; i++)
archiveInfo[i] = staticArchivers[i]->info;
@ -1143,16 +1143,11 @@ static int initStaticArchivers(void)
memcpy(archivers, staticArchivers, len);
return 1;
failed:
allocator.Free(archiveInfo);
allocator.Free(archivers);
archivers = NULL;
archiveInfo = NULL;
return 0;
} /* initStaticArchivers */
static int doDeinit(void);
int PHYSFS_init(const char *argv0)
{
BAIL_IF_MACRO(initialized, PHYSFS_ERR_IS_INITIALIZED, 0);
@ -1160,31 +1155,29 @@ int PHYSFS_init(const char *argv0)
if (!externalAllocator)
setDefaultAllocator();
if (allocator.Init != NULL)
BAIL_IF_MACRO(!allocator.Init(), ERRPASS, 0);
if ((allocator.Init != NULL) && (!allocator.Init())) return 0;
BAIL_IF_MACRO(!__PHYSFS_platformInit(), ERRPASS, 0);
BAIL_IF_MACRO(!initializeMutexes(), ERRPASS, 0);
baseDir = calculateBaseDir(argv0);
BAIL_IF_MACRO(!baseDir, ERRPASS, 0);
/* !!! FIXME: we have to clean up all the half-initialized state if something fails. */
userDir = __PHYSFS_platformCalcUserDir();
if (!userDir)
if (!__PHYSFS_platformInit())
{
allocator.Free(baseDir);
baseDir = NULL;
if (allocator.Deinit != NULL) allocator.Deinit();
return 0;
} /* if */
/* everything below here can be cleaned up safely by doDeinit(). */
if (!initializeMutexes()) goto initFailed;
baseDir = calculateBaseDir(argv0);
if (!baseDir) goto initFailed;
userDir = __PHYSFS_platformCalcUserDir();
if (!userDir) goto initFailed;
/* Platform layer is required to append a dirsep. */
assert(baseDir[strlen(baseDir) - 1] == __PHYSFS_platformDirSeparator);
assert(userDir[strlen(userDir) - 1] == __PHYSFS_platformDirSeparator);
BAIL_IF_MACRO(!initStaticArchivers(), ERRPASS, 0);
if (!initStaticArchivers()) goto initFailed;
initialized = 1;
@ -1192,6 +1185,10 @@ int PHYSFS_init(const char *argv0)
__PHYSFS_setError(PHYSFS_getLastErrorCode());
return 1;
initFailed:
doDeinit();
return 0;
} /* PHYSFS_init */
@ -1241,9 +1238,8 @@ static void freeSearchPath(void)
} /* freeSearchPath */
int PHYSFS_deinit(void)
static int doDeinit(void)
{
BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
BAIL_IF_MACRO(!__PHYSFS_platformDeinit(), ERRPASS, 0);
closeFileHandleList(&openWriteList);
@ -1285,14 +1281,21 @@ int PHYSFS_deinit(void)
allowSymLinks = 0;
initialized = 0;
__PHYSFS_platformDestroyMutex(errorLock);
__PHYSFS_platformDestroyMutex(stateLock);
if (errorLock) __PHYSFS_platformDestroyMutex(errorLock);
if (stateLock) __PHYSFS_platformDestroyMutex(stateLock);
if (allocator.Deinit != NULL)
allocator.Deinit();
errorLock = stateLock = NULL;
return 1;
} /* doDeinit */
int PHYSFS_deinit(void)
{
BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
return doDeinit();
} /* PHYSFS_deinit */