From f00f5cb51a31a6faac7902f15fe37f1eb9ca7d8e Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Fri, 1 Jan 2021 16:25:50 -0400 Subject: [PATCH] physfs: add PHYSFS_canUnmount Fix unmount on a RW archive not checking if writable files are open --- src/libraries/physfs/physfs.c | 41 +++++++++++++++++++++++++++++++++++ src/libraries/physfs/physfs.h | 6 +++++ 2 files changed, 47 insertions(+) diff --git a/src/libraries/physfs/physfs.c b/src/libraries/physfs/physfs.c index 6540fd86e..4b5decf07 100644 --- a/src/libraries/physfs/physfs.c +++ b/src/libraries/physfs/physfs.c @@ -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); diff --git a/src/libraries/physfs/physfs.h b/src/libraries/physfs/physfs.h index 9ec5e79e7..b08c02ce7 100644 --- a/src/libraries/physfs/physfs.h +++ b/src/libraries/physfs/physfs.h @@ -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)