physfs: add PHYSFS_canUnmount

Fix unmount on a RW archive not checking if writable files are open
This commit is contained in:
Alex Szpakowski
2021-01-01 16:25:50 -04:00
parent 2bee42893b
commit f00f5cb51a
2 changed files with 47 additions and 0 deletions
+41
View File
@@ -1104,6 +1104,23 @@ static int freeDirHandle(DirHandle *dh, FileHandle *openList)
} /* freeDirHandle */
static int dirHandleFilesOpen(DirHandle *dh, FileHandle *openList)
{
FileHandle *i;
if (dh == NULL)
return 0;
for (i = openList; i != NULL; i = i->next)
{
if (i->dirHandle == dh)
return 1;
}
return 0;
} /* dirHandleFilesOpen */
static char *calculateBaseDir(const char *argv0)
{
const char dirsep = __PHYSFS_platformDirSeparator;
@@ -1891,6 +1908,8 @@ int PHYSFS_unmount(const char *oldDir)
if (strcmp(i->dirName, oldDir) == 0)
{
next = i->next;
if (i->forWriting && dirHandleFilesOpen(i, openWriteList))
BAIL_MUTEX(PHYSFS_ERR_FILES_STILL_OPEN, stateLock, 0);
BAIL_IF_MUTEX_ERRPASS(!freeDirHandle(i, openReadList),
stateLock, 0);
@@ -1908,6 +1927,28 @@ int PHYSFS_unmount(const char *oldDir)
} /* PHYSFS_unmount */
int PHYSFS_canUnmount(const char *oldDir)
{
DirHandle *i;
BAIL_IF(oldDir == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0);
__PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next)
{
if (strcmp(i->dirName, oldDir) == 0)
{
if (i->forWriting && dirHandleFilesOpen(i, openWriteList))
BAIL_MUTEX(PHYSFS_ERR_OK, stateLock, 0);
if (dirHandleFilesOpen(i, openReadList))
BAIL_MUTEX(PHYSFS_ERR_OK, stateLock, 0);
BAIL_MUTEX(PHYSFS_ERR_OK, stateLock, 1);
}
}
BAIL_MUTEX(PHYSFS_ERR_NOT_MOUNTED, stateLock, 0);
} /* PHYSFS_canUnmount */
char **PHYSFS_getSearchPath(void)
{
return doEnumStringList(PHYSFS_getSearchPathCallback);
+6
View File
@@ -2787,6 +2787,12 @@ PHYSFS_DECL int PHYSFS_enumerate(const char *dir, PHYSFS_EnumerateCallback c,
*/
PHYSFS_DECL int PHYSFS_unmount(const char *oldDir);
/**
* \fn int PHYSFS_canUnmount(const char *oldDir)
* \brief Check whether a directory or archive can be unmounted.
*/
PHYSFS_DECL int PHYSFS_canUnmount(const char *oldDir);
/**
* \fn const PHYSFS_Allocator *PHYSFS_getAllocator(void)