X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FUtils%2FDaemon%2FDaemon.cc;h=2b758364dc702f6dcb551bcc0c6fc1afcd542cbf;hb=HEAD;hp=e705022cc979a9a5403aa0cbc565983e237cdaae;hpb=26610f603ebdd465307b9621f532c1fe19fd5571;p=senf.git diff --git a/senf/Utils/Daemon/Daemon.cc b/senf/Utils/Daemon/Daemon.cc index e705022..2b75836 100644 --- a/senf/Utils/Daemon/Daemon.cc +++ b/senf/Utils/Daemon/Daemon.cc @@ -2,23 +2,28 @@ // // 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 -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. +// The contents of this file are subject to the Fraunhofer FOKUS Public License +// Version 1.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// http://senf.berlios.de/license.html // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// The Fraunhofer FOKUS Public License Version 1.0 is based on, +// but modifies the Mozilla Public License Version 1.1. +// See the full license text for the amendments. // -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// Software distributed under the License is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +// for the specific language governing rights and limitations under the License. +// +// The Original Code is Fraunhofer FOKUS code. +// +// The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. +// (registered association), Hansastraße 27 c, 80686 Munich, Germany. +// All Rights Reserved. +// +// Contributor(s): +// Stefan Bund /** \file \brief Daemon non-inline non-template implementation */ @@ -35,12 +40,15 @@ #include #include #include -#include +#ifdef SENF_BACKTRACE + #include +#endif #include #include #include #include #include +#include #include #include #include @@ -51,7 +59,7 @@ //#include "Daemon.mpp" #define prefix_ -///////////////////////////////cc.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// #define LIBC_CALL(fn, args) if (fn args < 0) \ SENF_THROW_SYSTEM_EXCEPTION(#fn "()") @@ -59,7 +67,7 @@ #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() @@ -67,7 +75,7 @@ prefix_ senf::Daemon::~Daemon() if (pidfileCreated_) { try { LIBC_CALL( ::unlink, (pidfile_.c_str()) ); - } catch (Exception e) { + } catch (Exception & e) { // e << "; could not unlink " << pidfile_.c_str(); // throw; } @@ -84,12 +92,12 @@ 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_; } @@ -128,8 +136,8 @@ prefix_ void senf::Daemon::openLog() if (! stdoutLog_.empty()) { fd = ::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666); if (fd < 0) - SENF_THROW_SYSTEM_EXCEPTION("") - << " Could not open \"" << stdoutLog_ << "\" for redirecting stdout."; + SENF_THROW_SYSTEM_EXCEPTION( + " Could not open \"" + stdoutLog_ + "\" for redirecting stdout."); stdout_ = fd; } if (! stderrLog_.empty()) { @@ -137,12 +145,12 @@ prefix_ void senf::Daemon::openLog() stderr_ = ::dup(fd); if (stderr_ < 0) SENF_THROW_SYSTEM_EXCEPTION("::dup()"); - } + } else { fd = ::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666); if (fd < 0) - SENF_THROW_SYSTEM_EXCEPTION("") - << " Could not open \"" << stderrLog_ << "\" for redirecting stderr."; + SENF_THROW_SYSTEM_EXCEPTION( + " Could not open \"" + stderrLog_ + "\" for redirecting stderr."); stderr_ = fd; } } @@ -152,21 +160,21 @@ prefix_ void senf::Daemon::logReopen() { if (! stdoutLog_.empty()) { int fd (::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666)); - if (fd < 0) + if (fd < 0) goto error; - if (::dup2(fd, 1) < 0) + if (::dup2(fd, 1) < 0) goto error; if (stderrLog_ == stdoutLog_) { - if (::dup2(fd, 2) < 0) + 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) + if (fd < 0) goto error; - if (::dup2(fd, 2) < 0) + if (::dup2(fd, 2) < 0) goto error; } return; @@ -192,7 +200,7 @@ namespace { prefix_ void senf::Daemon::detach() { if (daemonize_ && ! detached_) { - // Wow .. ouch .. + // Wow .. ouch .. // To ensure all data is written to the console log file in the correct order, we suspend // execution here until the parent process tells us to continue via SIGUSR1: We block // SIGUSR1 and install our own signal handler saving the old handler and signal mask. Then @@ -260,7 +268,7 @@ prefix_ int senf::Daemon::start(int argc, char const ** argv) if (pidfileCreate()) pidfileCreated_ = true; else { - std::cerr << "PID file '" << pidfile_ + std::cerr << "PID file '" << pidfile_ << "' creation failed. Daemon running ?" << std::endl; return 1; } @@ -294,7 +302,7 @@ prefix_ senf::Daemon & senf::Daemon::instance() return *instance_; } -//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// // protected members prefix_ senf::Daemon::Daemon() @@ -307,17 +315,18 @@ prefix_ senf::Daemon::Daemon() senf::Daemon * senf::Daemon::instance_ (0); -//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// // private members prefix_ void senf::Daemon::configure() { // int i (not unsigned) since argc_ is int ... for (int i (1); i> old_pid) - || old_pid < 0 - || ::kill(old_pid, 0) >= 0 + || old_pid < 0 + || ::kill(old_pid, 0) >= 0 || errno == EPERM ) { LIBC_CALL( ::unlink, (tempname.c_str()) ); return false; @@ -480,7 +487,7 @@ prefix_ bool senf::Daemon::pidfileCreate() LIBC_CALL( ::unlink, (tempname.c_str() )); if (::link(pidfile_.c_str(), tempname.c_str()) < 0) { if (errno != ENOENT) - SENF_THROW_SYSTEM_EXCEPTION("") << linkErrorFormat % tempname % pidfile_; + SENF_THROW_SYSTEM_EXCEPTION( (linkErrorFormat % tempname % pidfile_).str()); // Hmm ... the pidfile mysteriously disappeared ... try again. continue; } @@ -493,7 +500,7 @@ prefix_ bool senf::Daemon::pidfileCreate() return false; } } - + { std::ofstream pidf (tempname.c_str()); pidf << ::getpid() << std::endl; @@ -517,9 +524,9 @@ namespace { if (sig == SIGSEGV) std::cerr << "Invalid memory access at " << info->si_addr << "\n"; - +#ifdef SENF_BACKTRACE static void * entries[SENF_DEBUG_BACKTRACE_NUMCALLERS]; - unsigned nEntries( ::backtrace(entries, SENF_DEBUG_BACKTRACE_NUMCALLERS) ); + int nEntries( ::backtrace(entries, SENF_DEBUG_BACKTRACE_NUMCALLERS) ); // Hack the callers address into the backtrace // entries[1] = reinterpret_cast(ucontext->uc_mcontext.gregs[REG_EIP]); @@ -527,7 +534,7 @@ namespace { std::cerr << "Backtrace:\n"; senf::formatBacktrace(std::cerr, entries, nEntries); std::cerr << "-- \n"; - +#endif //SENF_BACKTRACE if (sig != SIGUSR2) { ::signal(sig, SIG_DFL); ::kill(::getpid(), sig); @@ -536,7 +543,7 @@ namespace { } -#endif +#endif // SENF_DEBUG namespace { void sighupHandler(int sig) @@ -568,13 +575,15 @@ prefix_ void senf::Daemon::installSighandlers() ::sigaction(SIGFPE, &sa, NULL); ::sigaction(SIGBUS, &sa, NULL); ::sigaction(SIGSEGV, &sa, NULL); +#ifdef SIGSTKFLT //SIGSTKFLT is used for stack faults on coprocessors. That condition doesn't exist on MIPS ::sigaction(SIGSTKFLT, &sa, NULL); +#endif ::sigaction(SIGSYS, &sa, NULL); ::sigaction(SIGUSR2, &sa, NULL); #endif } -/////////////////////////////////////////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::detail::DaemonWatcher prefix_ senf::detail::DaemonWatcher::DaemonWatcher(int pid, int coutpipe, int cerrpipe, @@ -583,8 +592,8 @@ prefix_ senf::detail::DaemonWatcher::DaemonWatcher(int pid, int coutpipe, int ce stderr_(stderr), sigChld_(false), cldSignal_ (SIGCHLD, senf::membind(&DaemonWatcher::sigChld, this)), timer_ ("senf::detail::DaemonWatcher::childOk", senf::membind(&DaemonWatcher::childOk, this)), - coutForwarder_(coutpipe_, boost::bind(&DaemonWatcher::pipeClosed, this, 1)), - cerrForwarder_(cerrpipe_, boost::bind(&DaemonWatcher::pipeClosed, this, 2)) + coutForwarder_(coutpipe_, boost::bind(&DaemonWatcher::pipeClosed, this, 1)), + cerrForwarder_(cerrpipe_, boost::bind(&DaemonWatcher::pipeClosed, this, 2)) { coutForwarder_.addTarget(1); if (stdout_ >= 0) @@ -599,7 +608,7 @@ prefix_ void senf::detail::DaemonWatcher::run() scheduler::process(); } -//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// // private members prefix_ void senf::detail::DaemonWatcher::pipeClosed(int id) @@ -645,11 +654,18 @@ prefix_ void senf::detail::DaemonWatcher::childOk() scheduler::terminate(); } -/////////////////////////////////////////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::detail::DaemonWatcher::Forwarder +prefix_ senf::detail::DaemonWatcher::Forwarder::Target::Target(Forwarder & fwd, int fd_) + : fd (fd_), offset (0), + writeevent ("senf::detail::DaemonWatcher::Forwarder::Target::writeevent", + boost::bind(&Forwarder::writeData, &fwd, _1, this), + fd, scheduler::FdEvent::EV_WRITE, false) +{} + prefix_ senf::detail::DaemonWatcher::Forwarder::Forwarder(int src, Callback cb) - : src_(src), cb_(cb), + : src_(src), cb_(cb), readevent_("senf::detail::DaemonWatcher::Forwarder::readevent", senf::membind(&Forwarder::readData, this), src_, scheduler::FdEvent::EV_READ) {} @@ -672,16 +688,16 @@ prefix_ void senf::detail::DaemonWatcher::Forwarder::readData(int event) while (1) { n = ::read(src_,buf,1024); if (n<0) { - if (errno != EINTR) + if (errno != EINTR) SENF_THROW_SYSTEM_EXCEPTION("::read()"); - } - else + } + else break; } if (n == 0) { if (buffer_.empty()) - cb_(); + cb_(); src_ = -1; readevent_.disable(); return; @@ -698,7 +714,7 @@ prefix_ void senf::detail::DaemonWatcher::Forwarder::readData(int event) } prefix_ void senf::detail::DaemonWatcher::Forwarder::writeData(int event, Target * target) -{ +{ if (event != scheduler::FdEvent::EV_WRITE) { // Broken pipe while writing data ? Not much, we can do here, we just drop the data targets_.erase_and_destroy(Targets::current(*target),DestroyDelete()); @@ -736,7 +752,7 @@ prefix_ void senf::detail::DaemonWatcher::Forwarder::writeData(int event, Target #undef LIBC_CALL #undef LIBC_CALL_RV -///////////////////////////////cc.e//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// #undef prefix_ //#include "Daemon.mpp"