- do not use POSIX directory functions in common code.

For Windows these need to redirect to Unicode system functions to properly handle paths not representable in 8 bit encodings.
This commit is contained in:
Christoph Oelckers 2022-08-17 09:55:47 +02:00
parent c5f4967871
commit 8d3c1adf05
7 changed files with 76 additions and 22 deletions

View File

@ -53,6 +53,7 @@
#include "findfile.h" #include "findfile.h"
#include "md5.h" #include "md5.h"
#include "i_specialpaths.h" #include "i_specialpaths.h"
#include "i_system.h"
extern FILE* Logfile; extern FILE* Logfile;
@ -178,12 +179,12 @@ UNSAFE_CCMD (crashout)
UNSAFE_CCMD (dir) UNSAFE_CCMD (dir)
{ {
FString dir, path; FString dir, path;
char curdir[256];
const char *match; const char *match;
findstate_t c_file; findstate_t c_file;
void *file; void *file;
if (!getcwd (curdir, countof(curdir))) FString curdir = I_GetCWD();
if (curdir.IsEmpty())
{ {
Printf ("Current path too long\n"); Printf ("Current path too long\n");
return; return;
@ -192,7 +193,7 @@ UNSAFE_CCMD (dir)
if (argv.argc() > 1) if (argv.argc() > 1)
{ {
path = NicePath(argv[1]); path = NicePath(argv[1]);
if (chdir(path)) if (!I_ChDir(path))
{ {
match = path; match = path;
dir = ExtractFilePath(path); dir = ExtractFilePath(path);
@ -208,7 +209,7 @@ UNSAFE_CCMD (dir)
{ {
match = "*"; match = "*";
} }
if (chdir (dir)) if (!I_ChDir(dir))
{ {
Printf ("%s not found\n", dir.GetChars()); Printf ("%s not found\n", dir.GetChars());
return; return;
@ -245,7 +246,7 @@ UNSAFE_CCMD (dir)
I_FindClose (file); I_FindClose (file);
} }
chdir (curdir); I_ChDir(curdir);
} }
//========================================================================== //==========================================================================

View File

@ -171,9 +171,24 @@ unsigned int I_MakeRNGSeed()
return static_cast<unsigned int>(arc4random()); return static_cast<unsigned int>(arc4random());
} }
FString I_GetCWD()
{
char curdir[PATH_MAX];
if (!getcwd(curdir, countof(curdir)))
{
return "";
}
return curdir;
}
bool I_ChDir(const char* path)
{
return chdir(path) == 0;
}
void I_OpenShellFolder(const char* folder) void I_OpenShellFolder(const char* folder)
{ {
char curdir[256]; char curdir[PATH_MAX];
if (!getcwd (curdir, countof(curdir))) if (!getcwd (curdir, countof(curdir)))
{ {
Printf ("Current path too long\n"); Printf ("Current path too long\n");

View File

@ -69,6 +69,8 @@ inline int I_GetNumaNodeCount() { return 1; }
inline int I_GetNumaNodeThreadCount(int numaNode) { return std::max<int>(std::thread::hardware_concurrency(), 1); } inline int I_GetNumaNodeThreadCount(int numaNode) { return std::max<int>(std::thread::hardware_concurrency(), 1); }
inline void I_SetThreadNumaNode(std::thread &thread, int numaNode) { } inline void I_SetThreadNumaNode(std::thread &thread, int numaNode) { }
FString I_GetCWD();
bool I_ChDir(const char* path);
void I_OpenShellFolder(const char*); void I_OpenShellFolder(const char*);
#endif #endif

View File

@ -410,6 +410,21 @@ FString I_GetFromClipboard (bool use_primary_selection)
return ""; return "";
} }
FString I_GetCWD()
{
char curdir[PATH_MAX];
if (!getcwd(curdir, countof(curdir)))
{
return "";
}
return curdir;
}
bool I_ChDir(const char* path)
{
return chdir(path) == 0;
}
// Return a random seed, preferably one with lots of entropy. // Return a random seed, preferably one with lots of entropy.
unsigned int I_MakeRNGSeed() unsigned int I_MakeRNGSeed()
{ {
@ -434,7 +449,7 @@ unsigned int I_MakeRNGSeed()
void I_OpenShellFolder(const char* folder) void I_OpenShellFolder(const char* folder)
{ {
char curdir[256]; char curdir[PATH_MAX];
if (!getcwd (curdir, countof(curdir))) if (!getcwd (curdir, countof(curdir)))
{ {
Printf ("Current path too long\n"); Printf ("Current path too long\n");

View File

@ -961,6 +961,25 @@ void I_SetThreadNumaNode(std::thread &thread, int numaNode)
} }
} }
FString I_GetCWD()
{
auto len = GetCurrentDirectoryW(0, nullptr);
TArray<wchar_t> curdir(len + 1, true);
if (!GetCurrentDirectoryW(len + 1, curdir.Data()))
{
return "";
}
FString returnv(curdir.Data());
FixPathSeperator(returnv);
return returnv;
}
bool I_ChDir(const char* path)
{
return SetCurrentDirectoryW(WideString(path).c_str());
}
void I_OpenShellFolder(const char* infolder) void I_OpenShellFolder(const char* infolder)
{ {
auto len = GetCurrentDirectoryW(0, nullptr); auto len = GetCurrentDirectoryW(0, nullptr);

View File

@ -80,5 +80,7 @@ int I_GetNumaNodeThreadCount(int numaNode);
void I_SetThreadNumaNode(std::thread &thread, int numaNode); void I_SetThreadNumaNode(std::thread &thread, int numaNode);
void I_OpenShellFolder(const char*); void I_OpenShellFolder(const char*);
FString I_GetCWD();
bool I_ChDir(const char* path);
#endif #endif

View File

@ -37,6 +37,7 @@
#include "cmdlib.h" #include "cmdlib.h"
#include "printf.h" #include "printf.h"
#include "configfile.h" #include "configfile.h"
#include "i_system.h"
#ifndef _WIN32 #ifndef _WIN32
@ -369,9 +370,8 @@ void D_AddConfigFiles(TArray<FString>& wadfiles, const char* section, const char
void D_AddDirectory(TArray<FString>& wadfiles, const char* dir, const char *filespec, FConfigFile* config) void D_AddDirectory(TArray<FString>& wadfiles, const char* dir, const char *filespec, FConfigFile* config)
{ {
char curdir[ZPATH_MAX]; FString curdir = I_GetCWD();
if (curdir.IsNotEmpty())
if (getcwd(curdir, ZPATH_MAX))
{ {
char skindir[ZPATH_MAX]; char skindir[ZPATH_MAX];
findstate_t findstate; findstate_t findstate;
@ -387,7 +387,7 @@ void D_AddDirectory(TArray<FString>& wadfiles, const char* dir, const char *file
skindir[--stuffstart] = 0; skindir[--stuffstart] = 0;
} }
if (!chdir(skindir)) if (I_ChDir(skindir))
{ {
skindir[stuffstart++] = '/'; skindir[stuffstart++] = '/';
if ((handle = I_FindFirst(filespec, &findstate)) != (void*)-1) if ((handle = I_FindFirst(filespec, &findstate)) != (void*)-1)
@ -403,7 +403,7 @@ void D_AddDirectory(TArray<FString>& wadfiles, const char* dir, const char *file
I_FindClose(handle); I_FindClose(handle);
} }
} }
chdir(curdir); I_ChDir(curdir);
} }
} }
@ -417,27 +417,27 @@ void D_AddDirectory(TArray<FString>& wadfiles, const char* dir, const char *file
// //
//========================================================================== //==========================================================================
static FString BFSwad; // outside the function to evade C++'s insane rules for constructing static variables inside functions.
const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinprogdir, FConfigFile* config) const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinprogdir, FConfigFile* config)
{ {
static char wad[ZPATH_MAX];
if (file == nullptr || *file == '\0') if (file == nullptr || *file == '\0')
{ {
return nullptr; return nullptr;
} }
if (lookfirstinprogdir) if (lookfirstinprogdir)
{ {
mysnprintf(wad, countof(wad), "%s%s%s", progdir.GetChars(), progdir.Back() == '/' ? "" : "/", file); BFSwad.Format("%s%s%s", progdir.GetChars(), progdir.Back() == '/' ? "" : "/", file);
if (DirEntryExists(wad)) if (DirEntryExists(BFSwad))
{ {
return wad; return BFSwad.GetChars();
} }
} }
if (DirEntryExists(file)) if (DirEntryExists(file))
{ {
mysnprintf(wad, countof(wad), "%s", file); BFSwad.Format("%s", file);
return wad; return BFSwad.GetChars();
} }
if (config != nullptr && config->SetSection("FileSearch.Directories")) if (config != nullptr && config->SetSection("FileSearch.Directories"))
@ -454,10 +454,10 @@ const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinpr
dir = NicePath(value); dir = NicePath(value);
if (dir.IsNotEmpty()) if (dir.IsNotEmpty())
{ {
mysnprintf(wad, countof(wad), "%s%s%s", dir.GetChars(), dir.Back() == '/' ? "" : "/", file); BFSwad.Format("%s%s%s", dir.GetChars(), dir.Back() == '/' ? "" : "/", file);
if (DirEntryExists(wad)) if (DirEntryExists(BFSwad))
{ {
return wad; return BFSwad.GetChars();
} }
} }
} }