in src/modules/commandrunner/src/lib/CommandRunner.cpp [547:638]
int CommandRunner::PersistCommandStatus(const std::string& clientName, const Command::Status commandStatus)
{
int status = 0;
rapidjson::Document document;
rapidjson::Document statusDocument;
statusDocument.Parse(Command::Status::Serialize(commandStatus, false).c_str());
std::lock_guard<std::mutex> lock(m_diskCacheMutex);
std::ifstream file(m_persistedCacheFile);
if (file.good())
{
rapidjson::IStreamWrapper isw(file);
if (document.ParseStream(isw).HasParseError() || (!document.IsObject()))
{
document.Parse(m_defaultCacheTemplate);
}
}
else
{
document.Parse(m_defaultCacheTemplate);
}
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
if (document.HasMember(clientName.c_str()))
{
bool updated = false;
rapidjson::Value& client = document[clientName.c_str()];
if (!client.IsArray())
{
client.SetArray();
}
for (auto& it : client.GetArray())
{
if (it.HasMember(g_commandId.c_str()) && it[g_commandId.c_str()].IsString() && (it[g_commandId.c_str()].GetString() == commandStatus.m_id))
{
it.CopyFrom(statusDocument, allocator);
updated = true;
break;
}
}
if (!updated)
{
if (client.Size() >= m_maxCacheSize)
{
client.Erase(client.Begin());
}
client.PushBack(statusDocument, allocator);
}
}
else
{
rapidjson::Value object(rapidjson::kArrayType);
object.PushBack(statusDocument, allocator);
document.AddMember(rapidjson::Value(clientName.c_str(), allocator), object, allocator);
}
rapidjson::StringBuffer buffer;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
document.Accept(writer);
if (buffer.GetSize() > 0)
{
std::FILE* file = std::fopen(m_persistedCacheFile, "w+");
if (nullptr == file)
{
OsConfigLogError(CommandRunnerLog::Get(), "Failed to open file: %s", m_persistedCacheFile);
status = EACCES;
}
else
{
int rc = std::fputs(buffer.GetString(), file);
if ((0 > rc) || (EOF == rc))
{
status = errno ? errno : EINVAL;
OsConfigLogError(CommandRunnerLog::Get(), "Failed write to file %s, error: %d %s", m_persistedCacheFile, status, errno ? strerror(errno) : "-");
}
fflush(file);
std::fclose(file);
RestrictFileAccessToCurrentAccountOnly(m_persistedCacheFile);
}
}
return status;
}