diff --git a/src/base/system.cpp b/src/base/system.cpp index a19eb66a3..b4f596003 100644 --- a/src/base/system.cpp +++ b/src/base/system.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -469,6 +470,19 @@ int io_flush(IOHANDLE io) return fflush((FILE *)io); } +int io_sync(IOHANDLE io) +{ + if(io_flush(io)) + { + return 1; + } +#if defined(CONF_FAMILY_WINDOWS) + return FlushFileBuffers((HANDLE)_get_osfhandle(_fileno((FILE *)io))) == 0; +#else + return fsync(fileno((FILE *)io)) != 0; +#endif +} + #define ASYNC_BUFSIZE 8 * 1024 #define ASYNC_LOCAL_BUFSIZE 64 * 1024 diff --git a/src/base/system.h b/src/base/system.h index 0db912cc4..b906cf182 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -303,6 +303,18 @@ int io_close(IOHANDLE io); */ int io_flush(IOHANDLE io); +/* + Function: io_sync + Synchronize file changes to disk. + + Parameters: + io - Handle to the file. + + Returns: + Returns 0 on success. +*/ +int io_sync(IOHANDLE io); + /* Function: io_error Checks whether an error occurred during I/O with the file. diff --git a/src/engine/shared/config.cpp b/src/engine/shared/config.cpp index 788082836..48301a23f 100644 --- a/src/engine/shared/config.cpp +++ b/src/engine/shared/config.cpp @@ -110,6 +110,11 @@ bool CConfigManager::Save() for(int i = 0; i < m_NumCallbacks; i++) m_aCallbacks[i].m_pfnFunc(this, m_aCallbacks[i].m_pUserData); + if(io_sync(m_ConfigFile) != 0) + { + m_Failed = true; + } + if(io_close(m_ConfigFile) != 0) m_Failed = true; diff --git a/src/test/io.cpp b/src/test/io.cpp index 51b7b9b57..69ae0f673 100644 --- a/src/test/io.cpp +++ b/src/test/io.cpp @@ -68,3 +68,13 @@ TEST(Io, CurrentExe) EXPECT_GE(io_length(CurrentExe), 1024); io_close(CurrentExe); } +TEST(Io, SyncWorks) +{ + CTestInfo Info; + IOHANDLE File = io_open(Info.m_aFilename, IOFLAG_WRITE); + ASSERT_TRUE(File); + EXPECT_EQ(io_write(File, "abc\n", 4), 4); + EXPECT_FALSE(io_sync(File)); + EXPECT_FALSE(io_close(File)); + EXPECT_FALSE(fs_remove(Info.m_aFilename)); +}