SConscript(glob.glob("*/SConscript"))
+SENFSCons.InstallIncludeFiles(env, [ 'parse_fixed_setup.hh' , 'parse_setup.hh' ])
ob = SConscript(sc)
if ob : objects.extend(ob)
-SENFSCons.InstallIncludeFiles(env, [ 'INet.hh', 'Raw.hh' ])
+SENFSCons.InstallIncludeFiles(env, [ 'INet.hh', 'Raw.hh', 'DVB.hh' ])
Return('objects')
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+// Stefan Bund <g0dil@berlios.de>
+//
+// 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.
+//
+// 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.
+//
+// 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.
+
+/** \file
+ \brief Daemon public header */
+
+#include "Daemon/Daemon.hh"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
prefix_ void senf::Daemon::detach()
{
- if (daemonize_) {
+ if (daemonize_ && ! detached_) {
// 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
LIBC_CALL( ::sigaction, (SIGUSR1, &oldact, 0) );
LIBC_CALL( ::sigprocmask, (SIG_SETMASK, &oldsig, 0) );
+
+ detached_ = true;
}
}
+namespace {
+ /* Purposely *not* derived from std::exception */
+ struct DaemonFailureException {
+ DaemonFailureException(unsigned c) : code(c) {}
+ unsigned code;
+ };
+}
+
+prefix_ void senf::Daemon::fail(unsigned code)
+{
+ throw DaemonFailureException(code);
+}
+
prefix_ int senf::Daemon::start(int argc, char const ** argv)
{
argc_ = argc;
argv_ = argv;
-# ifdef NDEBUG
-
try {
-
-# endif
-
configure();
if (daemonize_) {
}
main();
+ }
+ catch (DaemonFailureException & e) {
+ return e.code > 0 ? e.code : 1;
+ }
-# ifdef NDEBUG
+#ifdef NDEBUG
- }
catch (std::exception & e) {
std::cerr << "\n*** Fatal exception: " << e.what() << std::endl;
return 1;
/** \brief Daemon process
- This class provides the infrastructure to implement robust daemon processes. A daemon
- process is implemented by deriving from senf::Daemon and implementing the necessary
- (virtual) member functions.
- \code
- class MyDaemon : public senf::Daemon
- {
- void configure() {
- // Set configuration parameters like daemonize(), pidFile() etc.
- }
-
- void init() {
- // Initialize application. Setup all necessary objects. After init()
- // has completed, is startup should not fail anymore
- }
-
- void run() {
- // Main application code should be called here.
- }
- };
- \endcode
-
- The startup procedure is divided into three steps:
- \li First, configure() is called. configure() should be as simple as possible. It just needs
- to set the daemon parameters. No further setup should be done here.
- \li init() is called after fork() but while still connected to the terminal. init() should
- do all necessary application setup. Here, all configuration or user errors should be
- detected and properly diagnosed.
- \li After init() returns, the application will detach from the terminal. Now run() is called
- to enter the application main loop.
-
- Since there are times, where separating init() and run() into two separate functions is
- difficult, instead of defining init() and run(), the member main() may be defined. This
- member must call detach() as soon as initialization is completed to detach from the
- foreground terminal.
+ senf::Daemon provides simple management for daemon processes. Specifically, the Daemon class
+ implements
+ \li <i>Safe startup.</i> If the startup fails, the foreground process which launches the
+ daemon will terminate with an appropriate error exit code.
+ \li <i>Straight forward application initialization.</i> The daemon process is forked before
+ even initializing the application. The initialization procedure must not cater for a
+ later fork().
+ \li <i>Automatic pid file management.</i> The daemon will not be started, if a valid pid file is
+ found. Stale pid files are automatically removed.
+ \li <i>Console log management.</i> It is possible, to redirect standard output and error to
+ one or two log files. Messages pertaining to application initialization will be written
+ to both the console and the log file whereas later messages will be directed to the log
+ file only.
+ \li <i>Optional foreground execution.</i> The daemon may be started in the foreground for
+ debugging purposes. In this case, the console log file(s) is/are automatically
+ suppressed.
+
+ Starting the daemon process proceeds along the following steps:
+ \li The daemon is started by calling the daemon class instances start() member. This
+ normally happens from the \c main() function generated by \ref SENF_DAEMON_MAIN().
+ \li configure() is called. This (virtual) member configures the daemon manager by calling
+ the Daemon class parameter members.
+ \li The log files are opened, \c fork() is called and the pid file is checked and
+ created. The parent (foreground) process keeps running overseeing the daemon process.
+ \li main() is called. This virtual member may optionally be overridden in the derived
+ class. Here we assume, main() is not overridden so the default implementation is used.
+ \li main() calls init().
+ \li after init() returns, main() calls detach().
+ \li detach() signals successful startup to the parent process. The parent process terminates
+ leaving the daemon process running in the background.
+ \li main() calls run()
+ \li If run() ever returns, the daemon process terminates.
+ \li Whenever the process terminates normally (not necessarily successfully), the pid file is
+ automatically removed.
+
+ The parameter members are used from configure() to configure the daemon manager. See below
+ for details. The \e default configure() implementation will scan the command line arguments
+ to check for the following parameters:
+
+ <table class="senf">
+
+ <tr><td><tt>--no-daemon</tt></td><td>Run in foreground</td></tr>
+
+ <tr><td><tt>--console-log=</tt><i>stdout</i>[<tt>,</tt><i>stderr</i>]</td><td>Set the
+ console log file(s). If only \a stdout is specified (with no comma), the same log file
+ configuration will be applied to the standard output and error stream. Otherwise each stream
+ is assigned it's own log file. If either log file name is empty, the command will not change
+ the log file of that stream, the default log file will be used. If the log file name is set
+ to 'none', the log file will be disabled.</td></tr>
+
+ <tr><td><tt>--pid-file=</tt><i>pidfile</i></td><td>Set pid file path</td></tr>
+
+ </table>
+
+ The default configure() implementation will use whatever parameters have been set beforehand
+ as default values. These default values should be set in a derived class configure()
+ implementation. After setting the default values, the configure() implementation may choose
+ to call this default configure() implementation to scan for command line parmeters. The
+ default configure() implementation does \e not completely parse the command line
+ arguments. It just checks, if any of above arguments are present and precesses them. Other
+ arguments are completely ignored. The command line parameters should be completely processed
+ within init().
+
*/
class Daemon : boost::noncopyable
{
ignored. */
void pidFile(std::string const &); ///< Configure pid file
+ /**< If a pid file is configured it will be checked on
+ daemon startup. If another running instance of the
+ daemon is detected, starting the daemon will fail. */
///\}
///\name Auxiliary helpers
int argc(); ///< Access command line parameter count
char const ** argv(); ///< Access command line parameters
- void fail(int code=1); ///< Terminate startup with failure
+ void fail(unsigned code=1); ///< Terminate daemon with failure
///\}
Daemon();
virtual void configure(); ///< Called before forking to configure the daemon class
+ /**< This default implementation will parser some command
+ line parameters. See the class documentation above. */
# ifdef DOXYGEN
protected:
@INCLUDE = "$(TOPDIR)/doclib/Doxyfile.global"
-PROJECT_NAME = libUtils_Daemon
+PROJECT_NAME = Daemon
GENERATE_TAGFILE = doc/Daemon.tag
ALPHABETICAL_INDEX = NO
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+// Stefan Bund <g0dil@berlios.de>
+//
+// 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.
+//
+// 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.
+//
+// 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.
+
+/** \mainpage Daemon process management
+
+ The Daemon class provides the infrastructure to implement robust daemon processes. A daemon
+ process is implemented by deriving from senf::Daemon and implementing the necessary (virtual)
+ member functions.
+ \code
+ class MyDaemon : public senf::Daemon
+ {
+ void configure() {
+ // Set configuration parameters like daemonize(), pidFile() etc
+ consoleLog("MyDaemon.log");
+ // The default version provided by senf::Daemon will parse some special command line
+ // parameters to configure the daemon manager. You may optionally call this version
+ // here after setting default parameters
+ senf::Daemon::configure();
+ }
+
+ void init() {
+ // Initialize application. Setup all necessary objects. After init()
+ // has completed, the startup should not fail
+ }
+
+ void run() {
+ // Main application code should be called here.
+ }
+ };
+
+ // Provide main() function
+ SENF_DAEMON_MAIN(MyDaemon);
+ \endcode
+
+ The startup procedure is divided into three steps:
+ \li First, configure() is called. configure() should be as simple as possible. It just needs to
+ set the daemon parameters. No further setup should be done here.
+ \li init() is called after fork() but while still connected to the terminal. init() should do
+ all necessary application setup. Here, all configuration or user errors should be detected
+ and properly diagnosed.
+ \li After init() returns, the application will detach from the terminal. Now run() is called to
+ enter the application main loop.
+
+ Since there are times, where separating init() and run() into two separate functions is
+ difficult, instead of defining init() and run(), the member main() may be defined. This member
+ must call detach() as soon as initialization is completed to detach from the foreground
+ terminal.
+
+ \see
+ \ref senf::Daemon class \n
+ \ref SENF_DAEMON_MAIN() main() implementation macro
+ */
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// mode: flyspell
+// mode: auto-fill
+// End:
@INCLUDE = "$(TOPDIR)/doclib/Doxyfile.global"
-PROJECT_NAME = libLogger
+PROJECT_NAME = Logger
GENERATE_TAGFILE = doc/Logger.tag
ALPHABETICAL_INDEX = NO
sources = objects)
SENFSCons.Doxygen(env)
+SENFSCons.InstallIncludeFiles(env, [ 'Logger.hh', 'Daemon.hh' ])
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+// Stefan Bund <g0dil@berlios.de>
+//
+// 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.
+//
+// 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.
+//
+// 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.
+
+/** \file
+ \brief preprocessor.test unit tests */
+
+//#include "preprocessor.test.hh"
+//#include "preprocessor.test.ih"
+
+// Custom includes
+#include "preprocessor.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+// Nothing to really to test ...
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
table.senf {
width: 95%;
- margin: 0 auto;
+ margin: 10pt auto;
border: 1px solid #AAAAAA;
padding: 2px;
border-spacing: 0;
background-color: #EEEEEE;
padding: 2px 4px;
text-align: left;
+ vertical-align: top;
}
table.senf th {
}
table.listing {
- margin: 0;
+ margin: 10pt 0;
padding: 0;
border-spacing: 0;
border: none;