removed some useless spaces; not very important, I know :)
[senf.git] / Utils / Daemon / Daemon.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
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         senf::Daemon provides simple management for daemon processes. Specifically, the Daemon class
40         implements
41         \li <i>Safe startup.</i> If the startup fails, the foreground process which launches the
42             daemon will terminate with an appropriate error exit code.
43         \li <i>Straight forward application initialization.</i> The daemon process is forked before
44             even initializing the application. The initialization procedure must not cater for a
45             later fork().
46         \li <i>Automatic pid file management.</i> The daemon will not be started, if a valid pid file is
47             found. Stale pid files are automatically removed.
48         \li <i>Console log management.</i> It is possible, to redirect standard output and error to
49             one or two log files. Messages pertaining to application initialization will be written
50             to both the console and the log file whereas later messages will be directed to the log
51             file only.
52         \li <i>Optional foreground execution.</i> The daemon may be started in the foreground for
53             debugging purposes. In this case, the console log file(s) is/are automatically
54             suppressed.
55         
56         Starting the daemon process proceeds along the following steps:
57         \li The daemon is started by calling the daemon class instances start() member. This
58             normally happens from the \c main() function generated by \ref SENF_DAEMON_MAIN().
59         \li configure() is called. This (virtual) member configures the daemon manager by calling
60             the Daemon class parameter members.
61         \li The log files are opened, \c fork() is called and the pid file is checked and
62             created. The parent (foreground) process keeps running overseeing the daemon process.
63         \li main() is called. This virtual member may optionally be overridden in the derived
64             class. Here we assume, main() is not overridden so the default implementation is used.
65         \li main() calls init(). 
66         \li after init() returns, main() calls detach().
67         \li detach() signals successful startup to the parent process. The parent process terminates
68             leaving the daemon process running in the background.
69         \li main() calls run()
70         \li If run() ever returns, the daemon process terminates.
71         \li Whenever the process terminates normally (not necessarily successfully), the pid file is
72             automatically removed.
73
74         The parameter members are used from configure() to configure the daemon manager. See below
75         for details. The \e default configure() implementation will scan the command line arguments
76         to check for the following parameters:
77
78         <table class="senf">
79
80         <tr><td><tt>--no-daemon</tt></td><td>Run in foreground</td></tr>
81
82         <tr><td><tt>--console-log=</tt><i>stdout</i>[<tt>,</tt><i>stderr</i>]</td><td>Set the
83         console log file(s). If only \a stdout is specified (with no comma), the same log file
84         configuration will be applied to the standard output and error stream. Otherwise each stream
85         is assigned it's own log file. If either log file name is empty, the command will not change
86         the log file of that stream, the default log file will be used. If the log file name is set
87         to 'none', the log file will be disabled.</td></tr>
88
89         <tr><td><tt>--pid-file=</tt><i>pidfile</i></td><td>Set pid file path</td></tr>
90
91         </table>
92
93         The default configure() implementation will use whatever parameters have been set beforehand
94         as default values. These default values should be set in a derived class configure()
95         implementation. After setting the default values, the configure() implementation may choose
96         to call this default configure() implementation to scan for command line parmeters.  The
97         default configure() implementation does \e not completely parse the command line
98         arguments. It just checks, if any of above arguments are present and precesses them. Other
99         arguments are completely ignored. The command line parameters should be completely processed
100         within init().
101         
102       */
103     class Daemon : boost::noncopyable
104     {
105     public:
106         ///////////////////////////////////////////////////////////////////////////
107         // Types
108         
109         /// Select standard stream to redirect
110         enum StdStream { 
111             StdOut  /** Standard output stream */
112         ,   StdErr  /** Standard error stream */
113         ,   Both    /** Both, standard output and error stream */
114         }; 
115
116         ///////////////////////////////////////////////////////////////////////////
117         ///\name Structors and default members
118         ///\{
119
120         virtual ~Daemon();
121
122         ///\}
123         ///\name Parameters
124         ///\{
125
126         void daemonize(bool);           ///< Configure whether to run in fore- or background
127         bool daemon();                  ///< \c true, if running as daemon
128
129         void consoleLog(std::string const &, StdStream which = Both); 
130                                         ///< Configure console log file
131                                         /**< May be called multiple times to set the log file
132                                              for stdout and stderr seperately. Any standard stream
133                                              not assigned to a log file will be redirected to
134                                              <tt>/dev/null</tt>. 
135
136                                              When running in the foreground, the log files will be
137                                              ignored. */
138
139         void pidFile(std::string const &); ///< Configure pid file
140                                         /**< If a pid file is configured it will be checked on
141                                              daemon startup. If another running instance of the
142                                              daemon is detected, starting the daemon will fail. */
143
144         ///\}
145         ///\name Auxiliary helpers
146         ///\{
147
148         void detach();                  ///< Detach into background now
149                                         /**< This is \e not the same as forking. The process will
150                                              already have forked into the background but until
151                                              detach() is called (either automatically after init()
152                                              returns or manually), the front end (foreground)
153                                              process will wait for the background process to ensure
154                                              successful startup. */
155
156         int argc();                     ///< Access command line parameter count
157         char const ** argv();           ///< Access command line parameters
158
159         static void exit(unsigned code=0);     ///< Terminate daemon with failure
160
161         ///\}
162         
163         int start(int argc, char const ** argv); ///< Called from main() to launch daemon.
164                                         /**< Normally not called directly but from the
165                                              \ref SENF_DAEMON_MAIN macro. */
166
167     protected:
168         Daemon();
169
170         virtual void configure();       ///< Called before forking to configure the daemon class
171                                         /**< This default implementation will parser some command
172                                              line parameters. See the class documentation above. */
173
174 #   ifdef DOXYGEN
175     protected:
176 #   else
177     private:
178 #   endif
179
180         virtual void main();            ///< Called after forking to execute the main application
181                                         /**< The default implementation will call init(), detach()
182                                              and then run(). It is preferred to override init() and
183                                              run() if possible. */
184         virtual void init();            ///< Called to initialize the main application
185                                         /**< While init() is running, the application still is
186                                              connected to the controlling terminal. Error messages
187                                              will be shown to the user.
188
189                                              This member is only called, if the default main()
190                                              implementation is not overridden. */
191         virtual void run();             ///< Called to execute main application
192                                         /**< Called after detaching from the controlling
193                                              terminal.
194
195                                              This member is only called, if the default main()
196                                              implementation is not overridden. */
197     private:
198
199         void openLog();
200         void fork();
201         bool pidfileCreate();
202
203         int argc_;
204         char const ** argv_;
205
206         bool daemonize_;
207         std::string stdoutLog_;
208         std::string stderrLog_;
209         int stdout_;
210         int stderr_;
211         std::string pidfile_;
212
213         bool detached_;
214     };
215
216     /** \brief Provide \c main() function
217
218         This macro will provide a \c main() function to launch the daemon process defined in \a
219         klass. \a klass must be a class derived from senf::Daemon.
220
221         \ingroup process
222      */
223 #   define SENF_DAEMON_MAIN(klass)                                                                \
224         int main(int argc, char const ** argv)                                                    \
225         {                                                                                         \
226             klass instance;                                                                       \
227             return instance.start(argc, argv);                                                    \
228         }
229
230 }
231
232 ///////////////////////////////hh.e////////////////////////////////////////
233 //#include "Daemon.cci"
234 //#include "Daemon.ct"
235 //#include "Daemon.cti"
236 #endif
237
238 \f
239 // Local Variables:
240 // mode: c++
241 // fill-column: 100
242 // comment-column: 40
243 // c-file-style: "senf"
244 // indent-tabs-mode: nil
245 // ispell-local-dictionary: "american"
246 // compile-command: "scons -u test"
247 // End: