Socket/Protocols/INet: Allow socket address string representation to omit the address...
[senf.git] / Utils / Daemon / Daemon.cc
index c60939a..f1ac715 100644 (file)
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-#define LIBC_CALL(fn, args) if (fn args < 0) throw SystemException(#fn "()")
-#define LIBC_CALL_RV(var, fn, args) int var (fn args); if (var < 0) throw SystemException(#fn "()")
+#define LIBC_CALL(fn, args) if (fn args < 0) \
+    SENF_THROW_SYSTEM_EXCEPTION(#fn "()")
+
+#define LIBC_CALL_RV(var, fn, args) \
+    int var (fn args); if (var < 0) SENF_THROW_SYSTEM_EXCEPTION(#fn "()")
 
 ///////////////////////////////////////////////////////////////////////////
 // senf::Daemon
 
 prefix_ senf::Daemon::~Daemon()
 {
-    if (! pidfile_.empty()) {
+    if (pidfileCreated_) {
         try {
             LIBC_CALL( ::unlink, (pidfile_.c_str()) );
-        } catch (SystemException e) {
-            e << "; could not unlink " << pidfile_.c_str();
-            throw;
+        } catch (Exception e) {
+            // e << "; could not unlink " << pidfile_.c_str();
+            // throw;
         }
     }
 }
@@ -74,11 +77,13 @@ prefix_ bool senf::Daemon::daemon()
     return daemonize_;
 }
 
-prefix_ int senf::Daemon::argc() {
+prefix_ int senf::Daemon::argc() 
+{
     return argc_;
 }
 
-prefix_ char const ** senf::Daemon::argv() {
+prefix_ char const ** senf::Daemon::argv() 
+{
     return argv_;
 }
 
@@ -98,7 +103,8 @@ prefix_ void senf::Daemon::openLog()
     if (! stdoutLog_.empty()) {
         fd = ::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666);
         if (fd < 0)
-            throw SystemException("::open()");
+            SENF_THROW_SYSTEM_EXCEPTION("")
+                  << " Could not open \"" << stdoutLog_ << "\" for redirecting stdout.";
         stdout_ = fd;
     }
     if (stderrLog_ == stdoutLog_)
@@ -106,7 +112,8 @@ prefix_ void senf::Daemon::openLog()
     else if (! stderrLog_.empty()) {
         fd = ::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666);
         if (fd < 0)
-            throw SystemException("::open()");
+            SENF_THROW_SYSTEM_EXCEPTION("")
+                  << " Could not open \"" << stderrLog_ << "\" for redirecting stderr.";
         stderr_ = fd;
     }
 }
@@ -154,7 +161,7 @@ prefix_ void senf::Daemon::detach()
         while (! signaled) {
             ::sigsuspend(&waitsig);
             if (errno != EINTR)
-                throw SystemException("::sigsuspend()");
+                SENF_THROW_SYSTEM_EXCEPTION("::sigsuspend()");
         }
 
         LIBC_CALL( ::sigaction, (SIGUSR1, &oldact, 0) );
@@ -189,10 +196,14 @@ prefix_ int senf::Daemon::start(int argc, char const ** argv)
             openLog();
             fork();
         }
-        if (! pidfile_.empty() && ! pidfileCreate()) {
-            std::cerr << "\n*** PID file '" << pidfile_ << "' creation failed. Daemon running ?" 
-                      << std::endl;
-            return 1;
+        if (! pidfile_.empty()) {
+            if (pidfileCreate())
+                pidfileCreated_ = true;
+            else {
+                std::cerr << "PID file '" << pidfile_ 
+                          << "' creation failed. Daemon running ?" << std::endl;
+                return 1;
+            }
         }
 
         main();
@@ -204,11 +215,11 @@ prefix_ int senf::Daemon::start(int argc, char const ** argv)
 #ifndef SENF_DEBUG
 
     catch (std::exception & e) {
-        std::cerr << "\n*** Fatal exception: " << e.what() << std::endl;
+        std::cerr << "\n*** Fatal exception: " << e.what() << "\n" << std::endl;
         return 1;
     }
     catch (...) {
-        std::cerr << "\n*** Fatal exception: (unknown)" << std::endl;
+        std::cerr << "\n*** Fatal exception: (unknown)" << "\n" << std::endl;
         return 1;
     }
 
@@ -222,7 +233,7 @@ prefix_ int senf::Daemon::start(int argc, char const ** argv)
 
 prefix_ senf::Daemon::Daemon()
     : argc_(0), argv_(0), daemonize_(true), stdout_(-1), stderr_(-1), pidfile_(""),
-      detached_(false)
+      pidfileCreated_(false), detached_(false)
 {}
 
 ////////////////////////////////////////
@@ -323,7 +334,7 @@ prefix_ bool senf::Daemon::pidfileCreate()
     // was some race condition, probably over NFS.
 
     std::string tempname;
-    boost::format linkErrorFormat("; could not link \"%1%\" to \"%2%\"");
+    boost::format linkErrorFormat(" Could not link \"%1%\" to \"%2%\".");
 
     {
         char hostname[HOST_NAME_MAX+1];
@@ -337,13 +348,18 @@ prefix_ bool senf::Daemon::pidfileCreate()
     while (1) {
         {
             std::ofstream pidf (tempname.c_str());
+            if (! pidf)
+                SENF_THROW_SYSTEM_EXCEPTION("")
+                      << " Could not open pidfile \"" << tempname << "\" for output.";
             pidf << ::getpid() << std::endl;
+            if (! pidf)
+                SENF_THROW_SYSTEM_EXCEPTION("")
+                      << " Could not write to pidfile \"" << tempname << "\".";
         }
 
         if (::link(tempname.c_str(), pidfile_.c_str()) < 0) {
             if (errno != EEXIST) 
-                throw SystemException("::link()")
-                    << linkErrorFormat % pidfile_.c_str() % tempname.c_str();
+                SENF_THROW_SYSTEM_EXCEPTION("") << linkErrorFormat % pidfile_ % tempname;
         }
         else {
             struct ::stat s;
@@ -359,8 +375,10 @@ prefix_ bool senf::Daemon::pidfileCreate()
             if ( ! (pidf >> old_pid)
                  || old_pid < 0 
                  || ::kill(old_pid, 0) >= 0 
-                 || errno == EPERM )
+                 || errno == EPERM ) {
+                LIBC_CALL( ::unlink, (tempname.c_str()) );
                 return false;
+            }
         }
 
         // If we reach this point, the pid file exists but the process mentioned within the
@@ -374,8 +392,7 @@ prefix_ bool senf::Daemon::pidfileCreate()
         LIBC_CALL( ::unlink, (tempname.c_str() ));
         if (::link(pidfile_.c_str(), tempname.c_str()) < 0) {
             if (errno != ENOENT)
-                throw SystemException("::link()")
-                    << linkErrorFormat % tempname.c_str() % pidfile_.c_str();
+                SENF_THROW_SYSTEM_EXCEPTION("") << linkErrorFormat % tempname % pidfile_;
             // Hmm ... the pidfile mysteriously disappeared ... try again.
             continue;
         }
@@ -438,7 +455,7 @@ prefix_ void senf::detail::DaemonWatcher::pipeClosed(int id)
         if (sigChld_)
             childDied(); // does not return
         if (::kill(childPid_, SIGUSR1) < 0)
-            if (errno != ESRCH) throw SystemException("::kill()");
+            if (errno != ESRCH) SENF_THROW_SYSTEM_EXCEPTION("::kill()");
         Scheduler::instance().timeout(
             Scheduler::instance().eventTime() + ClockService::seconds(1),
             senf::membind(&DaemonWatcher::childOk, this));
@@ -455,7 +472,7 @@ prefix_ void senf::detail::DaemonWatcher::sigChld()
 prefix_ void senf::detail::DaemonWatcher::childDied()
 {
     int status (0);
-    if (::waitpid(childPid_,&status,0) < 0) throw SystemException("::waitpid()");
+    if (::waitpid(childPid_,&status,0) < 0) SENF_THROW_SYSTEM_EXCEPTION("::waitpid()");
     if (WIFSIGNALED(status)) {
         ::signal(WTERMSIG(status),SIG_DFL);
         ::kill(::getpid(), WTERMSIG(status));
@@ -506,7 +523,7 @@ prefix_ void senf::detail::DaemonWatcher::Forwarder::readData(Scheduler::EventId
     while (1) {
         n = ::read(src_,buf,1024);
         if (n<0) {
-            if (errno != EINTR) throw SystemException("::read()");
+            if (errno != EINTR) SENF_THROW_SYSTEM_EXCEPTION("::read()");
         } else 
             break;
     }
@@ -550,7 +567,7 @@ prefix_ void senf::detail::DaemonWatcher::Forwarder::writeData(Scheduler::EventI
 
     int w (::write(target->fd, buf, n));
     if (w < 0) {
-        if (errno != EINTR) throw SystemException("::write()");
+        if (errno != EINTR) SENF_THROW_SYSTEM_EXCEPTION("::write()");
         return;
     }
     target->offset += w;