Skip to content

Commit 425235f

Browse files
committed
INISettingsInterface: Fix file leak on Linux
1 parent 9d3f328 commit 425235f

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

src/util/ini_settings_interface.cpp

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,49 @@ Log_SetChannel(INISettingsInterface);
1919
#include <io.h> // _mktemp_s
2020
#else
2121
#include <stdlib.h> // mktemp
22+
#include <unistd.h>
2223
#endif
2324

2425
// To prevent races between saving and loading settings, particularly with game settings,
2526
// we only allow one ini to be parsed at any point in time.
2627
static std::mutex s_ini_load_save_mutex;
2728

28-
static std::string GetTemporaryFileName(const std::string& original_filename)
29+
static std::FILE* GetTemporaryFile(std::string* temporary_filename, const std::string& original_filename,
30+
const char* mode, Error* error)
2931
{
30-
std::string temporary_filename;
31-
temporary_filename.reserve(original_filename.length() + 8);
32-
temporary_filename.append(original_filename);
32+
temporary_filename->clear();
33+
temporary_filename->reserve(original_filename.length() + 8);
34+
temporary_filename->append(original_filename);
3335

3436
#ifdef _WIN32
35-
temporary_filename.append(".XXXXXXX");
36-
_mktemp_s(temporary_filename.data(), temporary_filename.length() + 1);
37-
#else
38-
temporary_filename.append(".XXXXXX");
39-
#if defined(__linux__) || defined(__ANDROID__) || defined(__APPLE__)
40-
mkstemp(temporary_filename.data());
37+
temporary_filename->append(".XXXXXXX");
38+
const errno_t err = _mktemp_s(temporary_filename->data(), temporary_filename->length() + 1);
39+
if (err != 0)
40+
{
41+
Error::SetErrno(error, "_mktemp_s() failed: ", err);
42+
return nullptr;
43+
}
44+
45+
return FileSystem::OpenCFile(temporary_filename->c_str(), mode, error);
4146
#else
42-
mktemp(temporary_filename.data());
43-
#endif
44-
#endif
47+
temporary_filename->append(".XXXXXX");
48+
const int fd = mkstemp(temporary_filename->data());
49+
if (fd < 0)
50+
{
51+
Error::SetErrno(error, "mkstemp() failed: ", errno);
52+
return nullptr;
53+
}
54+
55+
std::FILE* fp = fdopen(fd, mode);
56+
if (!fp)
57+
{
58+
Error::SetErrno(error, "mkstemp() failed: ", errno);
59+
close(fd);
60+
return nullptr;
61+
}
4562

46-
return temporary_filename;
63+
return fp;
64+
#endif
4765
}
4866

4967
INISettingsInterface::INISettingsInterface(std::string filename) : m_filename(std::move(filename)), m_ini(true, true)
@@ -79,9 +97,9 @@ bool INISettingsInterface::Save(Error* error /* = nullptr */)
7997
}
8098

8199
std::unique_lock lock(s_ini_load_save_mutex);
82-
std::string temp_filename(GetTemporaryFileName(m_filename));
100+
std::string temp_filename;
101+
std::FILE* fp = GetTemporaryFile(&temp_filename, m_filename, "wb", error);
83102
SI_Error err = SI_FAIL;
84-
std::FILE* fp = FileSystem::OpenCFile(temp_filename.c_str(), "wb", error);
85103
if (fp)
86104
{
87105
err = m_ini.SaveFile(fp, false);

0 commit comments

Comments
 (0)