From 107f07da97fbab4c20fdf6c05fdb7dbe7b99e450 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 25 Mar 2012 16:13:23 -0400 Subject: [PATCH] Better cleanup if PHYSFS_init() fails halfway through. --- src/physfs.c | 57 +++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/physfs.c b/src/physfs.c index 02cc9242..30e00496 100644 --- a/src/physfs.c +++ b/src/physfs.c @@ -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); + if (!__PHYSFS_platformInit()) + { + if (allocator.Deinit != NULL) allocator.Deinit(); + return 0; + } /* if */ - BAIL_IF_MACRO(!initializeMutexes(), ERRPASS, 0); + /* everything below here can be cleaned up safely by doDeinit(). */ - baseDir = calculateBaseDir(argv0); - BAIL_IF_MACRO(!baseDir, ERRPASS, 0); + if (!initializeMutexes()) goto initFailed; - /* !!! FIXME: we have to clean up all the half-initialized state if something fails. */ + baseDir = calculateBaseDir(argv0); + if (!baseDir) goto initFailed; userDir = __PHYSFS_platformCalcUserDir(); - if (!userDir) - { - allocator.Free(baseDir); - baseDir = NULL; - return 0; - } /* if */ + 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 */