Daemon.h

00001 // $Id: Daemon.h 21 2010-09-05 04:18:17Z cschwarz1 $
00002 
00003 #ifndef BASE_DAEMON_H
00004 #define BASE_DAEMON_H
00005 
00006 #include <iostream>
00007 #include <ctime>
00008 #include "Config.h"
00009 #include "Global.h"
00010 #include "Log.h"
00011 #include "Mutex.h"
00012 #include "Process.h"
00013 #include "Socket.h"
00014 
00015 template<class T> int daemon_main(int argc, const char **argv, const char *domain = NULL) {
00016     int ret;
00017 
00018     if (domain && *domain)
00019         base::Global::setDomain(domain);
00020     else
00021         base::Global::setDomainFromExecutable(*argv);
00022     try {
00023         T daemon(*argv);
00024         base::Socket::init();
00025         if (daemon.readArguments(argc, argv))
00026             ret = daemon.service(argv);
00027         else
00028             ret = 1;
00029         base::Socket::finit();
00030     } catch (const base::Exception &ex) {
00031         std::cerr << *argv << ": " << ex << std::endl;
00032         ret = 4;
00033     } catch (const std::exception &ex) {
00034         std::cerr << *argv << ": " << (ex.what() ? ex.what() : "(null)") << std::endl;
00035         ret = 4;
00036     }
00037     return ret;
00038 }
00039 
00040 namespace base {
00042 
00046     class PPBASE_EXPORT Daemon: public Mutex {
00047     public:
00049         virtual ~Daemon();
00050 
00052 
00055         Log *getLog();
00056 
00058         Config *getConfig();
00059 
00061 
00064         bool getForeground() const;
00065 
00067 
00070         const String &getName() const;
00071 
00073 
00076         Process::pid_type getPid() const;
00077 
00079 
00082         time_t getTime() const;
00083 
00085 
00088         void getUptime(String &s);
00089 
00091 
00097         void log(Log::levels level, const char *func, const char *fmt, ...)
00098         #ifdef __GNUC__
00099             __attribute__((format(printf, 4, 5)))
00100         #endif
00101             ;
00102 
00104 
00110         bool readArguments(int argc, const char **argv, const char *args =
00111         #ifdef _WIN32
00112             "c:d:fhqsvV"
00113         #else
00114             "c:d:fhqsvVw"
00115         #endif
00116         );
00117 
00119 
00122         int service(const char **argv);
00123 
00124 protected:
00125     #ifdef _WIN32
00126         enum srvE {
00127             srvNone = 0,
00128             srvInstall,
00129             srvStart,
00130             srvStop,
00131             srvUninstall
00132         };
00133     #endif
00134 
00136 
00139         Daemon(const String &name);
00140 
00142         virtual void config();
00143 
00145         virtual void createThreads(bool init);
00146 
00147     #ifndef _WIN32
00148 
00149 
00154         Process::pid_type daemonize(bool createpid = true, bool exitparent = true);
00155 
00157         void dropRootPrivileges();
00158     #endif
00159 
00161 
00166         virtual bool dumpState(bool force);
00167 
00168     #ifndef _WIN32
00169 
00170 
00173         gid_t getGroupID() const;
00174 
00176 
00179         uid_t getUserID() const;
00180     #endif
00181 
00183 
00187         virtual bool handleArgument(int arg);
00188 
00190 
00193         bool hasExplicitUGID() const;
00194 
00196 
00199         virtual int loop() = 0;
00200 
00202 
00205         virtual bool needRootPrivileges();
00206 
00208         int serviceMain();
00209 
00214         virtual void shutdown();
00215 
00220         virtual void startup();
00221 
00223         virtual void terminateThreads();
00224 
00226 
00230         virtual void usage(const char *pgm, bool err) const;
00231 
00233 
00239         virtual void vlog(Log::levels level, const char *func, const char *fmt, va_list ap);
00240 
00241     #ifdef _WIN32
00242         int win32Service();
00243         static void WINAPI win32ServiceHandler(DWORD opcode);
00244         void win32ServiceMain(DWORD, LPWSTR *);
00245         static void WINAPI win32ServiceMainS(DWORD dw, LPWSTR *lpstr);
00246         void win32SetServiceStatus(DWORD status);
00247     #endif
00248 
00249         Config                 _cfg;              
00250         String                 _cfgfile;          
00251         bool                   _foreground;       
00252         u_longlong_t           _laststatedump;    
00253         Log                   *_log;              
00254         bool                   _logstderr;        
00255         int                    _maxopenfiles;     
00256         String                 _name;             
00257         Process::pid_type      _pid;              
00258         time_t                 _t_now;            
00259         time_t                 _t_start;          
00260         int                    _fdreserve;        
00261 
00262     #ifdef _WIN32
00263         enum srvE              _srvact;           
00264         WString                _srvname;          
00265         String                 _srvprefix;        
00266         SERVICE_STATUS_HANDLE  _srvsh;            
00267         SERVICE_STATUS         _srvst;            
00268     #else
00269         String                 _pidfile;          
00270         bool                   _watcher;          
00271     #endif
00272     };
00273 }
00274 
00275 #endif