summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibCore/ConfigFile.cpp
diff options
context:
space:
mode:
authornetworkException <git@nwex.de>2021-08-19 01:23:31 +0200
committerAndreas Kling <kling@serenityos.org>2021-08-22 01:32:25 +0200
commit2ea2d026c22460e70ac16afd4fa7d928093bb098 (patch)
tree20aa64a1682771e68aa5b3166a0494c51baae4b3 /Userland/Libraries/LibCore/ConfigFile.cpp
parentdee3b7b8c9e62e405f856ea7422c5e64949d7b44 (diff)
downloadserenity-2ea2d026c22460e70ac16afd4fa7d928093bb098.zip
LibCore: Support using a file descriptor for opening ConfigFile
This patch adds support for opening a ConfigFile using a file descriptor rather than trying to open a the file by name directly. In contrast to the previous implementation, ConfigFile now always keeps a reference to an open File and does not reopen it for writing. This requires providing an additional argument to open functions if a file gets opened based on its name and the user of the api intends to write to the file in the future.
Diffstat (limited to 'Userland/Libraries/LibCore/ConfigFile.cpp')
-rw-r--r--Userland/Libraries/LibCore/ConfigFile.cpp58
1 files changed, 34 insertions, 24 deletions
diff --git a/Userland/Libraries/LibCore/ConfigFile.cpp b/Userland/Libraries/LibCore/ConfigFile.cpp
index 4e7ad28665..412aa393e1 100644
--- a/Userland/Libraries/LibCore/ConfigFile.cpp
+++ b/Userland/Libraries/LibCore/ConfigFile.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Jakob-Niklas See <git@nwex.de>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -13,35 +14,52 @@
namespace Core {
-NonnullRefPtr<ConfigFile> ConfigFile::get_for_lib(const String& lib_name)
+NonnullRefPtr<ConfigFile> ConfigFile::get_for_lib(String const& lib_name, AllowWriting allow_altering)
{
String directory = StandardPaths::config_directory();
auto path = String::formatted("{}/lib/{}.ini", directory, lib_name);
- return adopt_ref(*new ConfigFile(path));
+ return adopt_ref(*new ConfigFile(path, allow_altering));
}
-NonnullRefPtr<ConfigFile> ConfigFile::get_for_app(const String& app_name)
+NonnullRefPtr<ConfigFile> ConfigFile::get_for_app(String const& app_name, AllowWriting allow_altering)
{
String directory = StandardPaths::config_directory();
auto path = String::formatted("{}/{}.ini", directory, app_name);
- return adopt_ref(*new ConfigFile(path));
+ return adopt_ref(*new ConfigFile(path, allow_altering));
}
-NonnullRefPtr<ConfigFile> ConfigFile::get_for_system(const String& app_name)
+NonnullRefPtr<ConfigFile> ConfigFile::get_for_system(String const& app_name, AllowWriting allow_altering)
{
auto path = String::formatted("/etc/{}.ini", app_name);
- return adopt_ref(*new ConfigFile(path));
+ return adopt_ref(*new ConfigFile(path, allow_altering));
}
-NonnullRefPtr<ConfigFile> ConfigFile::open(const String& path)
+NonnullRefPtr<ConfigFile> ConfigFile::open(String const& filename, AllowWriting allow_altering)
{
- return adopt_ref(*new ConfigFile(path));
+ return adopt_ref(*new ConfigFile(filename, allow_altering));
}
-ConfigFile::ConfigFile(const String& filename)
- : m_filename(filename)
+NonnullRefPtr<ConfigFile> ConfigFile::open(String const& filename, int fd)
{
+ return adopt_ref(*new ConfigFile(filename, fd));
+}
+
+ConfigFile::ConfigFile(const String& filename, AllowWriting allow_altering)
+ : m_file(File::construct(filename))
+{
+ if (!m_file->open(allow_altering == AllowWriting::Yes ? OpenMode::ReadWrite : OpenMode::ReadOnly))
+ return;
+
+ reparse();
+}
+
+ConfigFile::ConfigFile(String const& filename, int fd)
+ : m_file(File::construct(filename))
+{
+ if (!m_file->open(fd, OpenMode::ReadWrite, File::ShouldCloseFileDescriptor::Yes))
+ return;
+
reparse();
}
@@ -54,14 +72,10 @@ void ConfigFile::reparse()
{
m_groups.clear();
- auto file = File::construct(m_filename);
- if (!file->open(OpenMode::ReadOnly))
- return;
-
HashMap<String, String>* current_group = nullptr;
- while (file->can_read_line()) {
- auto line = file->read_line();
+ while (m_file->can_read_line()) {
+ auto line = m_file->read_line();
auto* cp = line.characters();
while (*cp && (*cp == ' ' || *cp == '\t' || *cp == '\n'))
@@ -149,19 +163,15 @@ bool ConfigFile::sync()
if (!m_dirty)
return true;
- FILE* fp = fopen(m_filename.characters(), "wb");
- if (!fp)
- return false;
+ m_file->truncate(0);
for (auto& it : m_groups) {
- outln(fp, "[{}]", it.key);
+ m_file->write(String::formatted("[{}]\n", it.key));
for (auto& jt : it.value)
- outln(fp, "{}={}", jt.key, jt.value);
- outln(fp);
+ m_file->write(String::formatted("{}={}\n", jt.key, jt.value));
+ m_file->write("\n");
}
- fclose(fp);
-
m_dirty = false;
return true;
}