From: Michael Friedrich Date: Tue, 29 Sep 2015 16:40:04 +0000 (+0200) Subject: Use a temporary file for modified-attributes.conf updates X-Git-Tag: v2.4.0~247 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=00712f1902b1786beb87e77a61ae2226ec218858;p=icinga2 Use a temporary file for modified-attributes.conf updates fixes #10238 --- diff --git a/lib/icinga/icingaapplication.cpp b/lib/icinga/icingaapplication.cpp index 6f531e101..a240b6944 100644 --- a/lib/icinga/icingaapplication.cpp +++ b/lib/icinga/icingaapplication.cpp @@ -169,9 +169,17 @@ static void PersistModAttrHelper(std::ofstream& fp, ConfigObject::Ptr& previousO void IcingaApplication::DumpProgramState(void) { ConfigObject::DumpObjects(GetStatePath()); + DumpModifiedAttributes(); +} +void IcingaApplication::DumpModifiedAttributes(void) +{ String path = GetModAttrPath(); - std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc); + String pathtmp = path + ".tmp"; + + std::ofstream fp; + fp.open(pathtmp.CStr(), std::ofstream::out | std::ofstream::trunc); + ConfigObject::Ptr previousObject; ConfigObject::DumpModifiedAttributes(boost::bind(&PersistModAttrHelper, boost::ref(fp), boost::ref(previousObject), _1, _2, _3)); @@ -180,6 +188,19 @@ void IcingaApplication::DumpProgramState(void) ConfigWriter::EmitValue(fp, 0, previousObject->GetVersion()); ConfigWriter::EmitRaw(fp, "\n}\n"); } + + fp.close(); + +#ifdef _WIN32 + _unlink(path.CStr()); +#endif /* _WIN32 */ + + if (rename(pathtmp.CStr(), path.CStr()) < 0) { + BOOST_THROW_EXCEPTION(posix_error() + << boost::errinfo_api_function("rename") + << boost::errinfo_errno(errno) + << boost::errinfo_file_name(pathtmp)); + } } IcingaApplication::Ptr IcingaApplication::GetInstance(void) diff --git a/lib/icinga/icingaapplication.hpp b/lib/icinga/icingaapplication.hpp index 4e66ff86d..0458cd2da 100644 --- a/lib/icinga/icingaapplication.hpp +++ b/lib/icinga/icingaapplication.hpp @@ -56,6 +56,7 @@ public: private: void DumpProgramState(void); + void DumpModifiedAttributes(void); virtual void OnShutdown(void) override; };