X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2FDaemon%2FDaemon.cc;h=f1ac715cd4367f870f8b07ea07412d3bbcdc256d;hb=d2459b6c8249291588fd3d0d125ed3d38e003b55;hp=7f1effe01bcbef5d077636f0cbda5720a3844da9;hpb=6cd42d47ebaa13d76c84afb0589372fdb2ab04b8;p=senf.git diff --git a/Utils/Daemon/Daemon.cc b/Utils/Daemon/Daemon.cc index 7f1effe..f1ac715 100644 --- a/Utils/Daemon/Daemon.cc +++ b/Utils/Daemon/Daemon.cc @@ -1,8 +1,8 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer NETwork research (NET) +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -38,6 +38,7 @@ #include #include #include +#include #include "../Exception.hh" #include "../membind.hh" @@ -45,16 +46,25 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -#define LIBC_CALL(fn, args) if (fn args < 0) throwErrno(#fn "()") -#define LIBC_CALL_RV(var, fn, args) int var (fn args); if (var < 0) throwErrno(#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()) - LIBC_CALL( ::unlink, (pidfile_.c_str()) ); + if (pidfileCreated_) { + try { + LIBC_CALL( ::unlink, (pidfile_.c_str()) ); + } catch (Exception e) { + // e << "; could not unlink " << pidfile_.c_str(); + // throw; + } + } } prefix_ void senf::Daemon::daemonize(bool v) @@ -67,6 +77,16 @@ prefix_ bool senf::Daemon::daemon() return daemonize_; } +prefix_ int senf::Daemon::argc() +{ + return argc_; +} + +prefix_ char const ** senf::Daemon::argv() +{ + return argv_; +} + prefix_ void senf::Daemon::consoleLog(std::string const & path, StdStream which) { switch (which) { @@ -83,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) - throwErrno("::open()"); + SENF_THROW_SYSTEM_EXCEPTION("") + << " Could not open \"" << stdoutLog_ << "\" for redirecting stdout."; stdout_ = fd; } if (stderrLog_ == stdoutLog_) @@ -91,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) - throwErrno("::open()"); + SENF_THROW_SYSTEM_EXCEPTION("") + << " Could not open \"" << stderrLog_ << "\" for redirecting stderr."; stderr_ = fd; } } @@ -139,7 +161,7 @@ prefix_ void senf::Daemon::detach() while (! signaled) { ::sigsuspend(&waitsig); if (errno != EINTR) - throwErrno("::sigsuspend()"); + SENF_THROW_SYSTEM_EXCEPTION("::sigsuspend()"); } LIBC_CALL( ::sigaction, (SIGUSR1, &oldact, 0) ); @@ -174,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(); @@ -186,14 +212,14 @@ prefix_ int senf::Daemon::start(int argc, char const ** argv) return e.code; } -#ifdef NDEBUG +#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; } @@ -207,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) {} //////////////////////////////////////// @@ -308,6 +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%\"."); { char hostname[HOST_NAME_MAX+1]; @@ -321,12 +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) - throwErrno("::link()"); + SENF_THROW_SYSTEM_EXCEPTION("") << linkErrorFormat % pidfile_ % tempname; } else { struct ::stat s; @@ -342,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 @@ -356,7 +391,8 @@ prefix_ bool senf::Daemon::pidfileCreate() LIBC_CALL( ::unlink, (tempname.c_str() )); if (::link(pidfile_.c_str(), tempname.c_str()) < 0) { - if (errno != ENOENT) throwErrno("::link()"); + if (errno != ENOENT) + SENF_THROW_SYSTEM_EXCEPTION("") << linkErrorFormat % tempname % pidfile_; // Hmm ... the pidfile mysteriously disappeared ... try again. continue; } @@ -419,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) throwErrno("::kill()"); + if (errno != ESRCH) SENF_THROW_SYSTEM_EXCEPTION("::kill()"); Scheduler::instance().timeout( Scheduler::instance().eventTime() + ClockService::seconds(1), senf::membind(&DaemonWatcher::childOk, this)); @@ -436,7 +472,7 @@ prefix_ void senf::detail::DaemonWatcher::sigChld() prefix_ void senf::detail::DaemonWatcher::childDied() { int status (0); - if (::waitpid(childPid_,&status,0) < 0) throwErrno("::waitpid()"); + if (::waitpid(childPid_,&status,0) < 0) SENF_THROW_SYSTEM_EXCEPTION("::waitpid()"); if (WIFSIGNALED(status)) { ::signal(WTERMSIG(status),SIG_DFL); ::kill(::getpid(), WTERMSIG(status)); @@ -487,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) throwErrno("::read()"); + if (errno != EINTR) SENF_THROW_SYSTEM_EXCEPTION("::read()"); } else break; } @@ -531,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) throwErrno("::write()"); + if (errno != EINTR) SENF_THROW_SYSTEM_EXCEPTION("::write()"); return; } target->offset += w;