summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/biboumi.1.md4
-rw-r--r--src/config/config.cpp1
-rw-r--r--src/main.cpp39
3 files changed, 36 insertions, 8 deletions
diff --git a/doc/biboumi.1.md b/doc/biboumi.1.md
index 334e65e..18482fb 100644
--- a/doc/biboumi.1.md
+++ b/doc/biboumi.1.md
@@ -57,6 +57,10 @@ The configuration file uses a simple format of the form
from 0 to 3. 0 is debug, 1 is info, 2 is warning, 3 is error. The
default is 0, but a more practical value for production use is 1.
+The configuration can be re-read at runtime (you can for example change the
+log level without having to restart biboumi) by sending SIGUSR1 or SIGUSR2
+(see kill(1)) to the process.
+
USAGE
-----
diff --git a/src/config/config.cpp b/src/config/config.cpp
index 5f937e6..82295d5 100644
--- a/src/config/config.cpp
+++ b/src/config/config.cpp
@@ -56,7 +56,6 @@ void Config::connect(t_config_changed_callback callback)
void Config::close()
{
Config* self = Config::instance().get();
- self->save_to_file();
self->values.clear();
Config::instance().reset();
}
diff --git a/src/main.cpp b/src/main.cpp
index 28f5a76..b27fd8b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -10,7 +10,9 @@
#include <signal.h>
// A flag set by the SIGINT signal handler.
-volatile std::atomic<bool> stop(false);
+static volatile std::atomic<bool> stop(false);
+// Flag set by the SIGUSR1/2 signal handler.
+static volatile std::atomic<bool> reload(false);
// A flag indicating that we are wanting to exit the process. i.e: if this
// flag is set and all connections are closed, we can exit properly.
static bool exiting = false;
@@ -35,6 +37,11 @@ static void sigint_handler(int, siginfo_t*, void*)
stop = true;
}
+static void sigusr_handler(int, siginfo_t*, void*)
+{
+ reload = true;
+}
+
int main(int ac, char** av)
{
if (ac > 1)
@@ -69,14 +76,21 @@ int main(int ac, char** av)
// config
sigset_t mask;
sigemptyset(&mask);
- struct sigaction on_sig;
- on_sig.sa_sigaction = &sigint_handler;
- on_sig.sa_mask = mask;
+ struct sigaction on_sigint;
+ on_sigint.sa_sigaction = &sigint_handler;
+ on_sigint.sa_mask = mask;
// we want to catch that signal only once.
// Sending SIGINT again will "force" an exit
- on_sig.sa_flags = SA_RESETHAND;
- sigaction(SIGINT, &on_sig, nullptr);
- sigaction(SIGTERM, &on_sig, nullptr);
+ on_sigint.sa_flags = SA_RESETHAND;
+ sigaction(SIGINT, &on_sigint, nullptr);
+ sigaction(SIGTERM, &on_sigint, nullptr);
+
+ // Install a signal to reload the config on SIGUSR1/2
+ struct sigaction on_sigusr;
+ on_sigusr.sa_sigaction = &sigusr_handler;
+ on_sigusr.sa_mask = mask;
+ sigaction(SIGUSR1, &on_sigusr, nullptr);
+ sigaction(SIGUSR2, &on_sigusr, nullptr);
const std::chrono::milliseconds timeout(-1);
while (p.poll(timeout) != -1 || !exiting)
@@ -91,6 +105,17 @@ int main(int ac, char** av)
stop = false;
xmpp_component->shutdown();
}
+ if (reload)
+ {
+ // Closing the config will just force it to be reopened the next time
+ // a configuration option is needed
+ log_info("Signal received, reloading the config...");
+ Config::close();
+ // Destroy the logger instance, to be recreated the next time a log
+ // line needs to be written
+ Logger::instance().reset();
+ reload = false;
+ }
// If the only existing connection is the one to the XMPP component:
// close the XMPP stream.
if (exiting && p.size() == 1 && xmpp_component->is_document_open())