From d27b7b29c3a1f5a7db0fbaf718728d04748ab021 Mon Sep 17 00:00:00 2001 From: Naim A Date: Sat, 23 Jan 2016 18:31:43 -0800 Subject: [PATCH] WIP: writing daemon + reloadable --- src/main.cpp | 102 +++++++++++++++++++++++--------------------- src/multiplatform.h | 2 + src/tracker.cpp | 50 ++++++++++++++++++++++ src/tracker.hpp | 35 +++++++++++++++ 4 files changed, 141 insertions(+), 48 deletions(-) create mode 100644 src/tracker.cpp create mode 100644 src/tracker.hpp diff --git a/src/main.cpp b/src/main.cpp index 71ae48c..8e0781b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,20 +30,50 @@ #include "udpTracker.hpp" #include "http/httpserver.hpp" #include "http/webapp.hpp" +#include "tracker.hpp" -UDPT::Logger *logger; +UDPT::Logger *logger = NULL; +UDPT::Tracker *instance = NULL; static void _signal_handler (int sig) { - std::stringstream ss; - ss << "Signal " << sig << " raised. "; - logger->log(Logger::LL_INFO, ss.str()); + switch (sig) + { + case SIGTERM: + instance->stop(); + break; + case SIGHUP: + break; + } } +#ifdef linux +static void daemonize(const boost::program_options::variables_map& conf) +{ + if (1 == ::getppid()) return; // already a daemon + int r = ::fork(); + if (0 > r) ::exit(-1); // failed to daemonize. + if (0 < r) ::exit(0); // parent exists. + + ::umask(0); + ::setsid(); + + // close all fds. + for (int i = ::getdtablesize(); i >=0; --i) + { + ::close(i); + } + + ::chdir(conf["daemon.chdir"].as().c_str()); + +} +#endif + int main(int argc, char *argv[]) { - int r; + Tracker& tracker = UDPT::Tracker::getInstance(); + instance = &tracker; #ifdef WIN32 WSADATA wsadata; @@ -56,6 +86,9 @@ int main(int argc, char *argv[]) ("all-help", "displays all help") ("test,t", "test configuration file") ("config,c", boost::program_options::value()->default_value("/etc/udpt.conf"), "configuration file to use") +#ifdef linux + ("interactive,i", "doesn't start as daemon") +#endif ; boost::program_options::options_description configOptions("Configuration options"); @@ -77,6 +110,10 @@ int main(int argc, char *argv[]) ("logging.filename", boost::program_options::value()->default_value("stdout"), "file to write logs to") ("logging.level", boost::program_options::value()->default_value("warning"), "log level (error/warning/info/debug)") + +#ifdef linux + ("daemon.chdir", boost::program_options::value()->default_value("/"), "home directory for daemon") +#endif ; boost::program_options::variables_map var_map; @@ -125,22 +162,11 @@ int main(int argc, char *argv[]) } } -#ifdef SIGBREAK - signal(SIGBREAK, &_signal_handler); -#endif -#ifdef SIGTERM - signal(SIGTERM, &_signal_handler); -#endif -#ifdef SIGABRT - signal(SIGABRT, &_signal_handler); -#endif -#ifdef SIGINT - signal(SIGINT, &_signal_handler); -#endif - + std::shared_ptr spLogger; try { - logger = new UDPT::Logger(var_map); + spLogger = std::shared_ptr(new UDPT::Logger(var_map)); + logger = spLogger.get(); } catch (const std::exception& ex) { @@ -148,40 +174,20 @@ int main(int argc, char *argv[]) return -1; } - std::shared_ptr tracker; - std::shared_ptr apiSrv; - std::shared_ptr webApp; - - try +#ifdef linux + if (!var_map.count("interactive")) { - tracker = std::shared_ptr(new UDPTracker(var_map)); - tracker->start(); - - if (var_map["apiserver.enable"].as()) - { - try - { - apiSrv = std::shared_ptr(new UDPT::Server::HTTPServer(var_map)); - webApp = std::shared_ptr(new UDPT::Server::WebApp(apiSrv, tracker->m_conn.get(), var_map)); - webApp->deploy(); - } - catch (const UDPT::Server::ServerException &e) - { - std::cerr << "ServerException #" << e.getErrorCode() << ": " << e.getErrorMsg() << endl; - } - } - } - catch (const UDPT::UDPTException& ex) - { - std::cerr << "UDPTException: " << ex.what() << std::endl; + daemonize(var_map); } + ::signal(SIGHUP, _signal_handler); + ::signal(SIGTERM, _signal_handler); +#endif - std::cout << "Hit Control-C to exit." << endl; - std::cin.get(); + tracker.start(var_map); + tracker.wait(); - tracker->stop(); + std::cerr << "Bye." << std::endl; - std::cout << endl << "Goodbye." << endl; #ifdef WIN32 ::WSACleanup(); #endif diff --git a/src/multiplatform.h b/src/multiplatform.h index 6dc3a33..d837c9f 100644 --- a/src/multiplatform.h +++ b/src/multiplatform.h @@ -36,11 +36,13 @@ #elif defined (linux) #include #include +#include #include #include #include #include #include +#include #define SOCKET int #define INVALID_SOCKET 0 diff --git a/src/tracker.cpp b/src/tracker.cpp new file mode 100644 index 0000000..df2093a --- /dev/null +++ b/src/tracker.cpp @@ -0,0 +1,50 @@ +#include "tracker.hpp" + +namespace UDPT +{ + Tracker::Tracker() + { + + } + + Tracker::~Tracker() + { + + } + + void Tracker::stop() + { + m_udpTracker->stop(); + wait(); + + m_apiSrv = nullptr; + m_webApp = nullptr; + m_udpTracker = nullptr; + } + + void Tracker::wait() + { + m_udpTracker->wait(); + } + + void Tracker::start(const boost::program_options::variables_map& conf) + { + m_udpTracker = std::shared_ptr(new UDPTracker(conf)); + + if (conf["apiserver.enable"].as()) + { + m_apiSrv = std::shared_ptr(new UDPT::Server::HTTPServer(conf)); + m_webApp = std::shared_ptr(new UDPT::Server::WebApp(m_apiSrv, m_udpTracker->conn, conf)); + m_webApp->deploy(); + } + + m_udpTracker->start(); + } + + Tracker& Tracker::getInstance() + { + static Tracker s_tracker; + + return s_tracker; + } +} diff --git a/src/tracker.hpp b/src/tracker.hpp new file mode 100644 index 0000000..0a0ea73 --- /dev/null +++ b/src/tracker.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include "logging.h" +#include "multiplatform.h" +#include "udpTracker.hpp" +#include "http/httpserver.hpp" +#include "http/webapp.hpp" + +namespace UDPT +{ + class Tracker + { + public: + + virtual ~Tracker(); + + void stop(); + + void start(const boost::program_options::variables_map& conf); + + void wait(); + + static Tracker& getInstance(); + + private: + std::shared_ptr m_udpTracker; + std::shared_ptr m_apiSrv; + std::shared_ptr m_webApp; + + Tracker(); + }; +}