@@ -19,31 +19,49 @@ Log_SetChannel(INISettingsInterface);
19
19
#include < io.h> // _mktemp_s
20
20
#else
21
21
#include < stdlib.h> // mktemp
22
+ #include < unistd.h>
22
23
#endif
23
24
24
25
// To prevent races between saving and loading settings, particularly with game settings,
25
26
// we only allow one ini to be parsed at any point in time.
26
27
static std::mutex s_ini_load_save_mutex;
27
28
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)
29
31
{
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);
33
35
34
36
#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);
41
46
#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
+ }
45
62
46
- return temporary_filename;
63
+ return fp;
64
+ #endif
47
65
}
48
66
49
67
INISettingsInterface::INISettingsInterface (std::string filename) : m_filename(std::move(filename)), m_ini(true , true )
@@ -79,9 +97,9 @@ bool INISettingsInterface::Save(Error* error /* = nullptr */)
79
97
}
80
98
81
99
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);
83
102
SI_Error err = SI_FAIL;
84
- std::FILE* fp = FileSystem::OpenCFile (temp_filename.c_str (), " wb" , error);
85
103
if (fp)
86
104
{
87
105
err = m_ini.SaveFile (fp, false );
0 commit comments