From 334c92bb49071b075a422d68105ddf873d911011 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Jul 2014 13:48:45 -0400 Subject: [PATCH] daemonization. --- Daemon.cpp | 31 ++++++++++++++----------------- DaemonLinux.cpp | 33 ++++++++++++++++++--------------- Log.cpp | 4 +--- Log.h | 30 +++++++++++++++++++++++++++--- Queue.h | 12 ++++++++---- i2p.cpp | 10 ++++++---- 6 files changed, 74 insertions(+), 46 deletions(-) diff --git a/Daemon.cpp b/Daemon.cpp index f5ee6549..8b7fcd6e 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -55,7 +55,17 @@ namespace i2p i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"), i2p::util::config::GetArg("-port", 17007)); - if (isLogging == 1) + LogPrint("CMD parameters:"); + for (int i = 0; i < argc; ++i) + LogPrint(i, " ", argv[i]); + + return true; + } + + bool Daemon_Singleton::start() + { + // initialize log + if (isLogging) { std::string logfile_path = i2p::util::filesystem::GetDataDir().string(); #ifndef _WIN32 @@ -63,18 +73,9 @@ namespace i2p #else logfile_path.append("\\debug.log"); #endif - g_Log.SetLogFile (logfile_path); - - LogPrint("CMD parameters:"); - for (int i = 0; i < argc; ++i) - LogPrint(i, " ", argv[i]); - + StartLog (logfile_path); } - return true; - } - - bool Daemon_Singleton::start() - { + d.httpServer = new i2p::util::HTTPServer(i2p::util::config::GetArg("-httpport", 7070)); d.httpServer->Start(); LogPrint("HTTPServer started"); @@ -115,15 +116,11 @@ namespace i2p LogPrint("NetDB stoped"); d.httpServer->Stop(); LogPrint("HTTPServer stoped"); + StopLog (); delete d.httpProxy; d.httpProxy = nullptr; delete d.httpServer; d.httpServer = nullptr; - if (isLogging == 1) - { - fclose(stdout); - } - return true; } } diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index 119752ac..530eb077 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -48,24 +48,29 @@ namespace i2p { pid_t pid; pid = fork(); - if (pid > 0) - { - g_Log.Stop(); - return 0; - } - if (pid < 0) - { - return -1; - } + if (pid > 0) // parent + ::exit (EXIT_SUCCESS); + if (pid < 0) // error + return false; + + // child umask(0); int sid = setsid(); if (sid < 0) { LogPrint("Error, could not create process group."); - return -1; + return false; } chdir(i2p::util::filesystem::GetDataDir().string().c_str()); + + // close stdin/stdout/stderr descriptors + ::close (0); + ::open ("/dev/null", O_RDWR); + ::close (1); + ::open ("/dev/null", O_RDWR); + ::close (2); + ::open ("/dev/null", O_RDWR); } // Pidfile @@ -75,12 +80,12 @@ namespace i2p if (pidFilehandle == -1) { LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?"); - return -1; + return false; } if (lockf(pidFilehandle, F_TLOCK, 0) == -1) { LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?"); - return -1; + return false; } char pid[10]; sprintf(pid, "%d\n", getpid()); @@ -101,12 +106,10 @@ namespace i2p bool DaemonLinux::stop() { - Daemon_Singleton::stop(); - close(pidFilehandle); unlink(pidfile.c_str()); - return true; + return Daemon_Singleton::stop(); } } diff --git a/Log.cpp b/Log.cpp index 4a88f2ba..3f50d23a 100644 --- a/Log.cpp +++ b/Log.cpp @@ -1,12 +1,10 @@ #include "Log.h" -Log g_Log; +Log * g_Log = nullptr; void LogMsg::Process() { output << s.str(); - - std::cout << s.str (); // TODO: delete later } void Log::Flush () diff --git a/Log.h b/Log.h index f3e7ae53..3abe0a28 100644 --- a/Log.h +++ b/Log.h @@ -37,7 +37,25 @@ class Log: public i2p::util::MsgQueue std::ofstream * m_LogFile; }; -extern Log g_Log; +extern Log * g_Log; + +inline void StartLog (const std::string& fullFilePath) +{ + if (!g_Log) + { + g_Log = new Log (); + g_Log->SetLogFile (fullFilePath); + } +} + +inline void StopLog () +{ + if (g_Log) + { + delete g_Log; + g_Log = nullptr; + } +} template void LogPrint (std::stringstream& s, TValue arg) @@ -55,10 +73,16 @@ void LogPrint (std::stringstream& s, TValue arg, TArgs... args) template void LogPrint (TArgs... args) { - LogMsg * msg = g_Log.GetLogFile () ? new LogMsg (*g_Log.GetLogFile ()) : new LogMsg (); + LogMsg * msg = (g_Log && g_Log->GetLogFile ()) ? new LogMsg (*g_Log->GetLogFile ()) : new LogMsg (); LogPrint (msg->s, args...); msg->s << std::endl; - g_Log.Put (msg); + if (g_Log) + g_Log->Put (msg); + else + { + msg->Process (); + delete msg; + } } #endif diff --git a/Queue.h b/Queue.h index 22f51e69..8cc5440e 100644 --- a/Queue.h +++ b/Queue.h @@ -65,7 +65,7 @@ namespace util return m_Queue.empty (); } - void WakeUp () { m_NonEmpty.notify_one (); }; + void WakeUp () { m_NonEmpty.notify_all (); }; Element * Get () { @@ -108,11 +108,15 @@ namespace util typedef std::function OnEmpty; MsgQueue (): m_IsRunning (true), m_Thread (std::bind (&MsgQueue::Run, this)) {}; + ~MsgQueue () { Stop (); }; void Stop() { - m_IsRunning = false; - Queue::WakeUp (); - m_Thread.join(); + if (m_IsRunning) + { + m_IsRunning = false; + Queue::WakeUp (); + m_Thread.join(); + } } void SetOnEmpty (OnEmpty const & e) { m_OnEmpty = e; }; diff --git a/i2p.cpp b/i2p.cpp index 2bd2b5b8..89966328 100644 --- a/i2p.cpp +++ b/i2p.cpp @@ -5,11 +5,13 @@ int main( int argc, char* argv[] ) { Daemon.init(argc, argv); - Daemon.start(); - while (Daemon.running) + if (Daemon.start()) { - //TODO Meeh: Find something better to do here. - std::this_thread::sleep_for (std::chrono::seconds(1)); + while (Daemon.running) + { + //TODO Meeh: Find something better to do here. + std::this_thread::sleep_for (std::chrono::seconds(1)); + } } Daemon.stop(); return EXIT_SUCCESS;