From 91aba16d98b97d5b2129f04f096d873c369f51b6 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 3 May 2016 23:01:49 +0100 Subject: [PATCH] Add daemonisation under Linux and other enhancements (from Simon G7RZU) --- Conf.cpp | 8 ++++++++ Conf.h | 2 ++ MMDVM.ini | 1 + MMDVMHost.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 93a6b28..7e7f6de 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -51,6 +51,7 @@ m_timeout(120U), m_duplex(true), m_modeHang(10U), m_display(), +m_daemon(false), m_rxFrequency(0U), m_txFrequency(0U), m_power(0U), @@ -191,6 +192,8 @@ bool CConf::read() m_modeHang = (unsigned int)::atoi(value); else if (::strcmp(key, "Display") == 0) m_display = value; + else if (::strcmp(key, "Daemon") == 0) + m_daemon = ::atoi(value) == 1; } else if (section == SECTION_INFO) { if (::strcmp(key, "TXFrequency") == 0) m_txFrequency = (unsigned int)::atoi(value); @@ -400,6 +403,11 @@ std::string CConf::getDisplay() const return m_display; } +bool CConf::getDaemon() const +{ + return m_daemon; +} + unsigned int CConf::getRxFrequency() const { return m_rxFrequency; diff --git a/Conf.h b/Conf.h index bd1b9ca..2e3e177 100644 --- a/Conf.h +++ b/Conf.h @@ -36,6 +36,7 @@ public: bool getDuplex() const; unsigned int getModeHang() const; std::string getDisplay() const; + bool getDaemon() const; // The Info section unsigned int getRxFrequency() const; @@ -134,6 +135,7 @@ private: bool m_duplex; unsigned int m_modeHang; std::string m_display; + bool m_daemon; unsigned int m_rxFrequency; unsigned int m_txFrequency; diff --git a/MMDVM.ini b/MMDVM.ini index 9de6e3b..5f29c84 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -4,6 +4,7 @@ Timeout=180 Duplex=1 ModeHang=10 Display=None +Daemon=0 [Info] RXFrequency=435000000 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 327d931..d320a42 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -38,38 +38,53 @@ #if !defined(_WIN32) && !defined(_WIN64) #include #include +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) +const char* DEFAULT_INI_FILE = "mmdvm.ini"; +#else +const char* DEFAULT_INI_FILE = "/etc/mmdvm.ini"; #endif static bool m_killed = false; +static int m_signal = 0; #if !defined(_WIN32) && !defined(_WIN64) -static void sigHandler(int) +static void sigHandler(int signum) { m_killed = true; + m_signal = signum; } #endif const char* HEADER1 = "This software is for use on amateur radio networks only,"; const char* HEADER2 = "it is to be used for educational purposes only. Its use on"; const char* HEADER3 = "commercial networks is strictly prohibited."; -const char* HEADER4 = "Copyright(C) 2015, 2016 by Jonathan Naylor, G4KLX"; +const char* HEADER4 = "Copyright(C) 2015, 2016 by Jonathan Naylor, G4KLX and others"; int main(int argc, char** argv) { - if (argc == 1) { - ::fprintf(stderr, "Usage: MMDVMHost \n"); - return 1; - } + const char* iniFile = DEFAULT_INI_FILE; + if (argc > 1) + iniFile = argv[1]; #if !defined(_WIN32) && !defined(_WIN64) - ::signal(SIGUSR1, sigHandler); + ::signal(SIGTERM, sigHandler); + ::signal(SIGHUP, sigHandler); #endif - CMMDVMHost* host = new CMMDVMHost(std::string(argv[1])); + CMMDVMHost* host = new CMMDVMHost(std::string(iniFile)); int ret2 = host->run(); delete host; + if (m_signal == 15) + ::LogInfo("Caught SIGTERM. Exiting"); + + if (m_signal == 1) + ::LogInfo("Caught SIGHUP. Exiting"); + ::LogFinalise(); return ret2; @@ -108,6 +123,30 @@ int CMMDVMHost::run() return 1; } +#if !defined(_WIN32) && !defined(_WIN64) + bool m_daemon = m_conf.getDaemon(); + if (m_daemon) { + // Create new process + pid_t pid = ::fork(); + if (pid == -1) + return -1; + else if (pid != 0) + exit(EXIT_SUCCESS); + + // Create new session and process group + if (::setsid() == -1) + return -1; + + // Set the working directory to the root directory + if (::chdir("/") == -1) + return -1; + + ::close(STDIN_FILENO); + ::close(STDOUT_FILENO); + ::close(STDERR_FILENO); + } +#endif + LogInfo(HEADER1); LogInfo(HEADER2); LogInfo(HEADER3);