205dcadcfaf0eda033ce3c68538f0a7f54635836
[senf.git] / Scheduler / Daemon.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer NETwork research (NET)
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Daemon public header */
25
26 #ifndef HH_Daemon_
27 #define HH_Daemon_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31
32 //#include "Daemon.mpp"
33 ///////////////////////////////hh.p////////////////////////////////////////
34
35 namespace senf {
36
37     /** \brief Daemon process
38
39         This class provides the infrastructure to implement robust daemon processes. A daemon
40         process is implemented by deriving from senf::Daemon and implementing the necessary
41         (virtual) member functions.
42         \code
43         class MyDaemon : public senf::Daemon
44         {
45             void configure() {
46                 // Set configuration parameters like daemonize(), pidFile() etc.
47             }
48
49             void init() {
50                 // Initialize application. Setup all necessary objects. After init()
51                 // has completed, is startup should not fail anymore
52             }
53
54             void run() {
55                 // Main application code should be called here.
56             }
57         };
58         \endcode
59
60         The startup procedure is divided into three steps:
61         \li First, configure() is called. configure() should be as simple as possible. It just needs
62             to set the daemon parameters. No further setup should be done here.
63         \li init() is called after fork() but while still connected to the terminal. init() should
64             do all necessary application setup. Here, all configuration or user errors should be
65             detected and properly diagnosed.
66         \li After init() returns, the application will detach from the terminal. Now run() is called
67             to enter the application main loop.
68
69         Since there are times, where separating init() and run() into two separate functions is
70         difficult, instead of defining init() and run(), the member main() may be defined. This
71         member must call detach() as soon as initialization is completed to detach from the
72         foreground terminal.
73       */
74     class Daemon : boost::noncopyable
75     {
76     public:
77         ///////////////////////////////////////////////////////////////////////////
78         // Types
79         
80         /// Select standard stream to redirect
81         enum StdStream { 
82             StdOut  /** Standard output stream */
83         ,   StdErr  /** Standard error stream */
84         ,   Both    /** Both, standard output and error stream */
85         }; 
86
87         ///////////////////////////////////////////////////////////////////////////
88         ///\name Structors and default members
89         ///\{
90
91         virtual ~Daemon();
92
93         ///\}
94         ///\name Parameters
95         ///\{
96
97         void daemonize(bool);           ///< Configure whether to run in fore- or background
98         bool daemon();                  ///< \c true, if running as daemon
99
100         void consoleLog(std::string, StdStream which = Both); ///< Configure console log file
101                                         /**< May be called multiple times to set the log file
102                                              for stdout and stderr seperately. Any standard stream
103                                              not assigned to a log file will be redirected to
104                                              <tt>/dev/null</tt>. 
105
106                                              When running in the foreground, the log files will be
107                                              ignored. */
108
109         void pidFile(std::string, bool unique = true); ///< Configure pid file
110
111         ///\}
112         ///\name Auxiliary helpers
113         ///\{
114
115         void detach();                  ///< Detach into background now
116                                         /**< This is \e not the same as forking. The process will
117                                              already have forked into the background but until
118                                              detach() is called (either automatically after init()
119                                              returns or manually), the front end (foreground)
120                                              process will wait for the background process to ensure
121                                              successful startup. */
122
123         int argc();                     ///< Access command line parameter count
124         char const ** argv();           ///< Access command line parameters
125
126         void fail(int code=1);          ///< Terminate startup with failure
127
128         ///\}
129         
130         int start(int argc, char const ** argv); ///< Called from main() to launch daemon.
131                                         /**< Normally not called directly but from the
132                                              \ref SENF_DAEMON_MAIN macro. */
133
134     protected:
135         Daemon();
136
137 #   ifdef DOXYGEN
138     protected:
139 #   else
140     private:
141 #   endif
142
143         virtual void configure();       ///< Called before forking to configure the daemon class
144         virtual void main();            ///< Called after forking to execute the main application
145                                         /**< The default implementation will call init(), detach()
146                                              and then run(). It is preferred to override init() and
147                                              run() if possible. */
148         virtual void init();            ///< Called to initialize the main application
149                                         /**< While init() is running, the application still is
150                                              connected to the controlling terminal. Error messages
151                                              will be shown to the user.
152
153                                              This member is only called, if the default main()
154                                              implementation is not overridden. */
155         virtual void run();             ///< Called to execute main application
156                                         /**< Called after detaching from the controlling
157                                              terminal.
158
159                                              This member is only called, if the default main()
160                                              implementation is not overridden. */
161     private:
162
163         void fork();
164         void pidfileCreate();
165
166         int argc_;
167         char const ** argv_;
168
169         bool daemonize_;
170         int stdout_;
171         int stderr_;
172         std::string pidfile_;
173         bool unique_;
174
175         bool detached_;
176     };
177
178     /** \brief Provide \c main() function
179
180         This macro will provide a \c main() function to launch the daemon process defined in \a
181         klass. \a klass must be a class derived from senf::Daemon.
182
183         \ingroup process
184      */
185 #   define SENF_DAEMON_MAIN(klass)                                                                \
186         int main(int argc, char const ** argv)                                                    \
187         {                                                                                         \
188             klass instance;                                                                       \
189             return instance.start(argc, argv);                                                    \
190         }
191
192 }
193
194 ///////////////////////////////hh.e////////////////////////////////////////
195 //#include "Daemon.cci"
196 //#include "Daemon.ct"
197 //#include "Daemon.cti"
198 #endif
199
200 \f
201 // Local Variables:
202 // mode: c++
203 // fill-column: 100
204 // comment-column: 40
205 // c-file-style: "senf"
206 // indent-tabs-mode: nil
207 // ispell-local-dictionary: "american"
208 // compile-command: "scons -u test"
209 // End: