diff --git a/filesystem/dir.c b/filesystem/dir.c index 4dd2fdf1..b1ff0c69 100644 --- a/filesystem/dir.c +++ b/filesystem/dir.c @@ -13,14 +13,23 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ +#include "build.h" #include #include #include -#if XASH_POSIX -#include -#endif #include #include +#if XASH_POSIX +#include +#include +#endif +#if XASH_LINUX +#include +#ifndef FS_CASEFOLD_FL // for compatibility with older distros +#define FS_CASEFOLD_FL 0x40000000 +#endif // FS_CASEFOLD_FL +#endif // XASH_LINUX + #include "port.h" #include "filesystem_internal.h" #include "crtlib.h" @@ -41,6 +50,29 @@ typedef struct dir_s struct dir_s *entries; // sorted } dir_t; +static qboolean Platform_GetDirectoryCaseSensitivity( const char *dir ) +{ +#if XASH_WIN32 + return false; +#elif XASH_LINUX && defined( FS_IOC_GETFLAGS ) + int flags = 0; + int fd; + + fd = open( dir, O_RDONLY | O_NONBLOCK ); + if( fd < 0 ) + return true; + + if( ioctl( fd, FS_IOC_GETFLAGS, &flags ) < 0 ) + return true; + + close( fd ); + + return !FBitSet( flags, FS_CASEFOLD_FL ); +#else + return true; +#endif +} + static int FS_SortDirEntries( const void *_a, const void *_b ) { const dir_t *a = _a; @@ -82,10 +114,6 @@ static void FS_InitDirEntries( dir_t *dir, const stringlist_t *list ) static void FS_PopulateDirEntries( dir_t *dir, const char *path ) { -#if XASH_WIN32 // Windows is always case insensitive - dir->numentries = DIRENTRY_CASEINSENSITIVE; - dir->entries = NULL; -#else stringlist_t list; if( !FS_SysFolderExists( path )) @@ -95,6 +123,13 @@ static void FS_PopulateDirEntries( dir_t *dir, const char *path ) return; } + if( !Platform_GetDirectoryCaseSensitivity( path )) + { + dir->numentries = DIRENTRY_CASEINSENSITIVE; + dir->entries = NULL; + return; + } + stringlistinit( &list ); listdirectory( &list, path ); if( !list.numstrings ) @@ -107,7 +142,6 @@ static void FS_PopulateDirEntries( dir_t *dir, const char *path ) FS_InitDirEntries( dir, &list ); } stringlistfreecontents( &list ); -#endif } static int FS_FindDirEntry( dir_t *dir, const char *name )