use unittest include from util!
[senf.git] / Utils / Daemon / Daemon.cc
index fe55821..9457d8c 100644 (file)
@@ -92,6 +92,24 @@ prefix_ char ** senf::Daemon::argv()
     return argv_;
 }
 
+namespace {
+
+    struct IsDaemonOpt {
+        bool operator()(std::string const & str) const {
+            return str == "--no-daemon"
+                || boost::starts_with(str, std::string("--pid-file="))
+                || boost::starts_with(str, std::string("--console-log="));
+        }
+    };
+}
+
+prefix_ void senf::Daemon::removeDaemonArgs()
+{
+    char ** last (std::remove_if(argv_+1, argv_+argc_, IsDaemonOpt()));
+    *last = 0;
+    argc_ = last - argv_;
+}
+
 prefix_ void senf::Daemon::consoleLog(std::string const & path, StdStream which)
 {
     switch (which) {
@@ -123,6 +141,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)
 {
     pidfile_ = f;
@@ -234,13 +281,24 @@ prefix_ int senf::Daemon::start(int argc, char ** argv)
     return 0;
 }
 
+prefix_ senf::Daemon & senf::Daemon::instance()
+{
+    BOOST_ASSERT( instance_ );
+    return *instance_;
+}
+
 ////////////////////////////////////////
 // protected members
 
 prefix_ senf::Daemon::Daemon()
     : argc_(0), argv_(0), daemonize_(true), stdout_(-1), stderr_(-1), pidfile_(""),
       pidfileCreated_(false), detached_(false)
-{}
+{
+    BOOST_ASSERT( ! instance_ );
+    instance_ = this;
+}
+
+senf::Daemon * senf::Daemon::instance_ (0);
 
 ////////////////////////////////////////
 // private members
@@ -466,12 +524,25 @@ namespace {
 
 #endif
 
+namespace {
+    void sighupHandler(int sig)
+    {
+        senf::Daemon::instance().logReopen();
+    }
+}
+
 prefix_ void senf::Daemon::installSighandlers()
 {
-#ifdef SENF_DEBUG
     struct ::sigaction sa;
-    sa.sa_sigaction = &fatalSignalsHandler;
+
     ::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;
 
     ::sigaction(SIGILL,    &sa, NULL);