3526cb3f760d698807b07d2ffba9c96e343af468
[senf.git] / Utils / Daemon / 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 const &, StdStream which = Both); 
101                                         ///< Configure console log file
102                                         /**< May be called multiple times to set the log file
103                                              for stdout and stderr seperately. Any standard stream
104                                              not assigned to a log file will be redirected to
105                                              <tt>/dev/null</tt>. 
106
107                                              When running in the foreground, the log files will be
108                                              ignored. */
109
110         void pidFile(std::string const &); ///< Configure pid file
111
112         ///\}
113         ///\name Auxiliary helpers
114         ///\{
115
116         void detach();                  ///< Detach into background now
117                                         /**< This is \e not the same as forking. The process will
118                                              already have forked into the background but until
119                                              detach() is called (either automatically after init()
120                                              returns or manually), the front end (foreground)
121                                              process will wait for the background process to ensure
122                                              successful startup. */
123
124         int argc();                     ///< Access command line parameter count
125         char const ** argv();           ///< Access command line parameters
126
127         void fail(int code=1);          ///< Terminate startup with failure
128
129         ///\}
130         
131         int start(int argc, char const ** argv); ///< Called from main() to launch daemon.
132                                         /**< Normally not called directly but from the
133                                              \ref SENF_DAEMON_MAIN macro. */
134
135     protected:
136         Daemon();
137
138         virtual void configure();       ///< Called before forking to configure the daemon class
139
140 #   ifdef DOXYGEN
141     protected:
142 #   else
143     private:
144 #   endif
145
146         virtual void main();            ///< Called after forking to execute the main application
147                                         /**< The default implementation will call init(), detach()
148                                              and then run(). It is preferred to override init() and
149                                              run() if possible. */
150         virtual void init();            ///< Called to initialize the main application
151                                         /**< While init() is running, the application still is
152                                              connected to the controlling terminal. Error messages
153                                              will be shown to the user.
154
155                                              This member is only called, if the default main()
156                                              implementation is not overridden. */
157         virtual void run();             ///< Called to execute main application
158                                         /**< Called after detaching from the controlling
159                                              terminal.
160
161                                              This member is only called, if the default main()
162                                              implementation is not overridden. */
163     private:
164
165         void openLog();
166         void fork();
167         bool pidfileCreate();
168
169         int argc_;
170         char const ** argv_;
171
172         bool daemonize_;
173         std::string stdoutLog_;
174         std::string stderrLog_;
175         int stdout_;
176         int stderr_;
177         std::string pidfile_;
178
179         bool detached_;
180     };
181
182     /** \brief Provide \c main() function
183
184         This macro will provide a \c main() function to launch the daemon process defined in \a
185         klass. \a klass must be a class derived from senf::Daemon.
186
187         \ingroup process
188      */
189 #   define SENF_DAEMON_MAIN(klass)                                                                \
190         int main(int argc, char const ** argv)                                                    \
191         {                                                                                         \
192             klass instance;                                                                       \
193             return instance.start(argc, argv);                                                    \
194         }
195
196 }
197
198 ///////////////////////////////hh.e////////////////////////////////////////
199 //#include "Daemon.cci"
200 //#include "Daemon.ct"
201 //#include "Daemon.cti"
202 #endif
203
204 \f
205 // Local Variables:
206 // mode: c++
207 // fill-column: 100
208 // comment-column: 40
209 // c-file-style: "senf"
210 // indent-tabs-mode: nil
211 // ispell-local-dictionary: "american"
212 // compile-command: "scons -u test"
213 // End: