Skip to content
Snippets Groups Projects
Commit 6476a41f authored by g0dil's avatar g0dil
Browse files

Utils/Daemon: Add instance() and logReopen() member and bind SIGHUP to logReopen()

parent e01ba6d7
No related branches found
No related tags found
No related merge requests found
...@@ -123,6 +123,35 @@ prefix_ void senf::Daemon::openLog() ...@@ -123,6 +123,35 @@ prefix_ void senf::Daemon::openLog()
} }
} }
prefix_ void senf::Daemon::logReopen()
{
if (! stdoutLog_.empty()) {
int fd (::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666));
if (fd < 0)
goto error;
if (::dup2(fd, 1) < 0)
goto error;
if (stderrLog_ == stdoutLog_) {
if (::dup2(fd, 2) < 0)
goto error;
return;
}
}
if (! stderrLog_.empty()) {
int fd (::open(stderrLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666));
if (fd < 0)
goto error;
if (::dup2(fd, 2) < 0)
goto error;
}
return;
error:
SENF_LOG(
(senf::log::CRITICAL)
("log-file reopen failed: (" << errno << ") " << ::strerror(errno)) );
}
prefix_ void senf::Daemon::pidFile(std::string const & f) prefix_ void senf::Daemon::pidFile(std::string const & f)
{ {
pidfile_ = f; pidfile_ = f;
...@@ -234,13 +263,24 @@ prefix_ int senf::Daemon::start(int argc, char ** argv) ...@@ -234,13 +263,24 @@ prefix_ int senf::Daemon::start(int argc, char ** argv)
return 0; return 0;
} }
prefix_ senf::Daemon & senf::Daemon::instance()
{
BOOST_ASSERT( instance_ );
return *instance_;
}
//////////////////////////////////////// ////////////////////////////////////////
// protected members // protected members
prefix_ senf::Daemon::Daemon() prefix_ senf::Daemon::Daemon()
: argc_(0), argv_(0), daemonize_(true), stdout_(-1), stderr_(-1), pidfile_(""), : argc_(0), argv_(0), daemonize_(true), stdout_(-1), stderr_(-1), pidfile_(""),
pidfileCreated_(false), detached_(false) pidfileCreated_(false), detached_(false)
{} {
BOOST_ASSERT( ! instance_ );
instance_ = this;
}
senf::Daemon * senf::Daemon::instance_ (0);
//////////////////////////////////////// ////////////////////////////////////////
// private members // private members
...@@ -466,12 +506,25 @@ namespace { ...@@ -466,12 +506,25 @@ namespace {
#endif #endif
namespace {
void sighupHandler(int sig)
{
senf::Daemon::instance().logReopen();
}
}
prefix_ void senf::Daemon::installSighandlers() prefix_ void senf::Daemon::installSighandlers()
{ {
#ifdef SENF_DEBUG
struct ::sigaction sa; struct ::sigaction sa;
sa.sa_sigaction = &fatalSignalsHandler;
::sigemptyset(&sa.sa_mask); ::sigemptyset(&sa.sa_mask);
sa.sa_handler = &sighupHandler;
sa.sa_flags = SA_RESTART;
::sigaction(SIGHUP, &sa, NULL);
#ifdef SENF_DEBUG
sa.sa_sigaction = &fatalSignalsHandler;
sa.sa_flags = SA_RESTART | SA_SIGINFO; sa.sa_flags = SA_RESTART | SA_SIGINFO;
::sigaction(SIGILL, &sa, NULL); ::sigaction(SIGILL, &sa, NULL);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
// Custom includes // Custom includes
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include "../Logger/SenfLog.hh"
//#include "Daemon.mpp" //#include "Daemon.mpp"
///////////////////////////////hh.p//////////////////////////////////////// ///////////////////////////////hh.p////////////////////////////////////////
...@@ -103,6 +104,8 @@ namespace senf { ...@@ -103,6 +104,8 @@ namespace senf {
class Daemon : boost::noncopyable class Daemon : boost::noncopyable
{ {
public: public:
SENF_LOG_CLASS_AREA();
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Types // Types
...@@ -158,12 +161,18 @@ namespace senf { ...@@ -158,12 +161,18 @@ namespace senf {
static void exit(unsigned code=0); ///< Terminate daemon with failure static void exit(unsigned code=0); ///< Terminate daemon with failure
void logReopen(); ///< Reopen the log files
/**< This is used when rotating the logs. By default,
SIGHUP calls logReopen. */
///\} ///\}
int start(int argc, char ** argv); ///< Called from main() to launch daemon. int start(int argc, char ** argv); ///< Called from main() to launch daemon.
/**< Normally not called directly but from the /**< Normally not called directly but from the
\ref SENF_DAEMON_MAIN macro. */ \ref SENF_DAEMON_MAIN macro. */
static Daemon & instance(); ///< Return the Daemon instance
protected: protected:
Daemon(); Daemon();
...@@ -212,6 +221,8 @@ namespace senf { ...@@ -212,6 +221,8 @@ namespace senf {
bool pidfileCreated_; bool pidfileCreated_;
bool detached_; bool detached_;
static Daemon * instance_;
}; };
/** \brief Provide \c main() function /** \brief Provide \c main() function
......
...@@ -77,9 +77,11 @@ namespace { ...@@ -77,9 +77,11 @@ namespace {
return instance.start(argc, argv); return instance.start(argc, argv);
} }
int pid;
int run(int argc, char ** argv) int run(int argc, char ** argv)
{ {
int pid (::fork()); pid = ::fork();
if (pid < 0) throw senf::SystemException("::fork()"); if (pid < 0) throw senf::SystemException("::fork()");
if (pid == 0) { if (pid == 0) {
::_exit(myMain(argc, argv)); ::_exit(myMain(argc, argv));
...@@ -100,16 +102,29 @@ BOOST_AUTO_UNIT_TEST(testDaemon) ...@@ -100,16 +102,29 @@ BOOST_AUTO_UNIT_TEST(testDaemon)
BOOST_CHECK( ! boost::filesystem::exists("invalid.log") ); BOOST_CHECK( ! boost::filesystem::exists("invalid.log") );
BOOST_CHECK( ! boost::filesystem::exists("invalid.pid") ); BOOST_CHECK( ! boost::filesystem::exists("invalid.pid") );
BOOST_CHECK( boost::filesystem::exists("testDaemon.pid") ); BOOST_REQUIRE( boost::filesystem::exists("testDaemon.pid") );
BOOST_REQUIRE( boost::filesystem::exists("testDaemon.log") );
boost::filesystem::rename("testDaemon.log", "testDaemon.log.1");
{
std::ifstream pidFile ("testDaemon.pid");
int pid (0);
BOOST_REQUIRE( pidFile >> pid );
BOOST_REQUIRE( pid != 0 );
::kill(pid, SIGHUP);
}
delay(1000); delay(1000);
BOOST_CHECK( ! boost::filesystem::exists("testDaemon.pid") ); BOOST_CHECK( ! boost::filesystem::exists("testDaemon.pid") );
BOOST_REQUIRE( boost::filesystem::exists("testDaemon.log") ); BOOST_CHECK( boost::filesystem::exists("testDaemon.log") );
BOOST_REQUIRE( boost::filesystem::exists("testDaemon.log.1") );
std::ifstream log ("testDaemon.log"); std::ifstream log ("testDaemon.log.1");
std::stringstream data; std::stringstream data;
data << log.rdbuf(); data << log.rdbuf();
BOOST_CHECK_EQUAL( data.str(), "Running init()\nRunning run()\n" ); BOOST_CHECK_EQUAL( data.str(), "Running init()\nRunning run()\n" );
BOOST_CHECK_NO_THROW( boost::filesystem::remove("testDaemon.log") ); BOOST_CHECK_NO_THROW( boost::filesystem::remove("testDaemon.log") );
BOOST_CHECK_NO_THROW( boost::filesystem::remove("testDaemon.log.1") );
} }
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment