summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2025-01-11 10:36:20 +0100
committerRoland Reichwein <mail@reichwein.it>2025-01-11 10:36:20 +0100
commit3c7b85d8355c64dec5b4ce011753196d53774103 (patch)
treeb350ef977987dd5e4155ae71d2c836a762225d56
parentaa210ed8a27387882fc7fd0dcd7cf961a9adc88f (diff)
Added PIDFile
-rw-r--r--MainLoop.h3
-rw-r--r--Makefile3
-rw-r--r--PIDFile.cpp54
-rw-r--r--PIDFile.h19
-rw-r--r--config.cpp8
-rw-r--r--config.h3
6 files changed, 89 insertions, 1 deletions
diff --git a/MainLoop.h b/MainLoop.h
index 9cd19a1..bfa0084 100644
--- a/MainLoop.h
+++ b/MainLoop.h
@@ -6,6 +6,7 @@
#include "MIDI.h"
#include "PCM.h"
#include "UI.h"
+#include "PIDFile.h"
#include <boost/signals2.hpp>
@@ -22,6 +23,8 @@ private:
Config m_config;
+ PIDFile m_pid_file{m_config.get_programname()};
+
NoteClick m_note_click;
ClockClick m_clock_click;
InternalClick m_internal_click;
diff --git a/Makefile b/Makefile
index f48b8b2..991d020 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,8 @@ SRCS= \
ClockClick.cpp \
InternalClick.cpp \
BPMDetect.cpp \
- Touchpad.cpp
+ Touchpad.cpp \
+ PIDFile.cpp
HEADERS=$(SRCS:.cpp=.h)
diff --git a/PIDFile.cpp b/PIDFile.cpp
new file mode 100644
index 0000000..85f30d3
--- /dev/null
+++ b/PIDFile.cpp
@@ -0,0 +1,54 @@
+#include "PIDFile.h"
+
+#include "log.h"
+
+#include <libreichwein/file.h>
+#include <libreichwein/process.h>
+#include <fmt/format.h>
+
+#include <stdexcept>
+
+#include "unistd.h"
+
+namespace fs = std::filesystem;
+
+PIDFile::PIDFile(const std::string& programname): m_programname{programname}
+{
+ pid_t pid{getpid()};
+
+ std::string contents{std::to_string(static_cast<int>(pid))};
+
+ fs::path filename{get_filename()};
+
+ if (fs::exists(filename)) {
+ pid_t existing_pid{get_pid_from_file()};
+ if (Reichwein::Process::is_running(existing_pid)) {
+ throw std::runtime_error(fmt::format("Program already running at PID {}", existing_pid));
+ } else {
+ log_cout << fmt::format("Found stale PID file {}, removing.\n", filename.string());
+ }
+ }
+
+ try {
+ Reichwein::File::setFile(filename, contents);
+ } catch (const std::exception& ex) {
+ log_cout << fmt::format("Warning: Not able to write to file{}, ignoring.\n", filename.string());
+ }
+}
+
+PIDFile::~PIDFile()
+{
+ fs::remove(get_filename());
+}
+
+int PIDFile::get_pid_from_file() const
+{
+ std::string contents{Reichwein::File::getFile(get_filename())};
+ return std::stoul(contents);
+}
+
+fs::path PIDFile::get_filename() const
+{
+ return fs::path{"/var/run"} / m_programname;
+}
+
diff --git a/PIDFile.h b/PIDFile.h
new file mode 100644
index 0000000..3278b0e
--- /dev/null
+++ b/PIDFile.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <filesystem>
+#include <string>
+
+class PIDFile
+{
+public:
+ PIDFile(const std::string& programname);
+ ~PIDFile();
+
+private:
+ int get_pid_from_file() const;
+
+ std::filesystem::path get_filename() const;
+
+ std::string m_programname;
+};
+
diff --git a/config.cpp b/config.cpp
index f8bf89c..d0a7671 100644
--- a/config.cpp
+++ b/config.cpp
@@ -19,6 +19,8 @@ std::string config_filename = "click.cfg";
fs::path click_data_filename = "media/click.s16le";
+const std::string programname = "click";
+
Config::Config(int argc, char** argv):
m_argv(argc)
{
@@ -161,3 +163,9 @@ std::filesystem::path Config::get_click_data_filename() const
{
return fs::path{m_argv[0]}.parent_path() / click_data_filename;
}
+
+std::string Config::get_programname() const
+{
+ return programname;
+}
+
diff --git a/config.h b/config.h
index 062989d..2262223 100644
--- a/config.h
+++ b/config.h
@@ -20,6 +20,7 @@ const int click_latency_frames = 10000;
const int default_mode = 0; // 0 = note, 1 = clock, 2 = internal
const int default_output = 1; // 0 = off, 1 = on
extern std::filesystem::path click_data_filename;
+extern const std::string programname;
class Config
{
@@ -56,6 +57,8 @@ public:
std::filesystem::path get_click_data_filename() const;
+ std::string get_programname() const;
+
private:
std::string get_config_filename() const;