summaryrefslogtreecommitdiffabout
path: root/src
Unidiff
Diffstat (limited to 'src') (more/less context) (ignore whitespace changes)
-rw-r--r--src/dudki.cc5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/dudki.cc b/src/dudki.cc
index b769109..b4e95a7 100644
--- a/src/dudki.cc
+++ b/src/dudki.cc
@@ -1,64 +1,65 @@
1#include <unistd.h> 1#include <unistd.h>
2#include <signal.h> 2#include <signal.h>
3#include <syslog.h> 3#include <syslog.h>
4#include <iostream> 4#include <iostream>
5#include <fstream> 5#include <fstream>
6#include <stdexcept> 6#include <stdexcept>
7using namespace std; 7using namespace std;
8#include "configuration.h" 8#include "configuration.h"
9#include "util.h" 9#include "util.h"
10 10
11#include "config.h" 11#include "config.h"
12#ifdef HAVE_GETOPT_H 12#ifdef HAVE_GETOPT_H
13# include <getopt.h> 13# include <getopt.h>
14#endif 14#endif
15 15
16#ifndef DEFAULT_CONF_FILE 16#ifndef DEFAULT_CONF_FILE
17# define DEFAULT_CONF_FILE "/etc/dudki.conf" 17# define DEFAULT_CONF_FILE "/etc/dudki.conf"
18#endif 18#endif
19 19
20#define PHEADER PACKAGE " Version " VERSION 20#define PHEADER PACKAGE " Version " VERSION
21#define PCOPY "Copyright (c) 2004 Klever Group" 21#define PCOPY "Copyright (c) 2004 Klever Group"
22 22
23bool finishing = false; 23bool finishing = false;
24bool restarting = false;
24static char **_argv = NULL; 25static char **_argv = NULL;
25 26
26static void lethal_signal_handler(int signum) { 27static void lethal_signal_handler(int signum) {
27 syslog(LOG_NOTICE,"Lethal signal received. Terminating."); 28 syslog(LOG_NOTICE,"Lethal signal received. Terminating.");
28 finishing = true; 29 finishing = true;
29} 30}
30static void sighup_handler(int signum) { 31static void sighup_handler(int signum) {
31 syslog(LOG_NOTICE,"SUGHUP received, reloading."); 32 syslog(LOG_NOTICE,"SUGHUP received, reloading.");
32 execvp(_argv[0],_argv); 33 restarting = finishing = true;
33} 34}
34 35
35void check_herd(configuration& config) { 36void check_herd(configuration& config) {
36 for(processes_t::iterator i=config.processes.begin();i!=config.processes.end();++i) 37 for(processes_t::iterator i=config.processes.begin();i!=config.processes.end();++i)
37 i->second.check(i->first,config); 38 i->second.check(i->first,config);
38} 39}
39 40
40void signal_self(const configuration& config,int signum) { 41void signal_self(const configuration& config,int signum) {
41 ifstream pids(config.pidfile.c_str(),ios::in); 42 ifstream pids(config.pidfile.c_str(),ios::in);
42 if(!pids) 43 if(!pids)
43 throw runtime_error("Can't detect running instance"); 44 throw runtime_error("Can't detect running instance");
44 pid_t pid = 0; 45 pid_t pid = 0;
45 pids >> pid; 46 pids >> pid;
46 if(!pid) 47 if(!pid)
47 throw runtime_error("Can't detect running instance"); 48 throw runtime_error("Can't detect running instance");
48 if(pid==getpid()) 49 if(pid==getpid())
49 throw 0; 50 throw 0;
50 if(kill(pid,signum)) 51 if(kill(pid,signum))
51 throw runtime_error("Failed to signal running instance"); 52 throw runtime_error("Failed to signal running instance");
52} 53}
53 54
54int main(int argc,char **argv) { 55int main(int argc,char **argv) {
55 try { 56 try {
56 _argv = new char*[argc+1]; 57 _argv = new char*[argc+1];
57 if(!_argv) 58 if(!_argv)
58 throw runtime_error("memory allocation problem at the very start"); 59 throw runtime_error("memory allocation problem at the very start");
59 memmove(_argv,argv,sizeof(*_argv)*(argc+1)); 60 memmove(_argv,argv,sizeof(*_argv)*(argc+1));
60 string config_file = DEFAULT_CONF_FILE; 61 string config_file = DEFAULT_CONF_FILE;
61 enum { 62 enum {
62 op_default, 63 op_default,
63 op_work, 64 op_work,
64 op_hup, 65 op_hup,
@@ -208,42 +209,44 @@ int main(int argc,char **argv) {
208 config.daemonize = true; 209 config.daemonize = true;
209 }catch(int zero) { 210 }catch(int zero) {
210 // we throw zero in case we're ensuring that this very process is running. 211 // we throw zero in case we're ensuring that this very process is running.
211 // we don't have to daemonize if we're daemonic. 212 // we don't have to daemonize if we're daemonic.
212 config.daemonize = false; 213 config.daemonize = false;
213 } 214 }
214 case op_default: 215 case op_default:
215 case op_work: 216 case op_work:
216 { 217 {
217 if(config.daemonize) { 218 if(config.daemonize) {
218 pid_t pf = fork(); 219 pid_t pf = fork();
219 if(pf<0) 220 if(pf<0)
220 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to fork()"); 221 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to fork()");
221 if(pf) { 222 if(pf) {
222 _exit(0); 223 _exit(0);
223 } 224 }
224 } 225 }
225 pid_file pidfile; 226 pid_file pidfile;
226 pidfile.set(config.pidfile); 227 pidfile.set(config.pidfile);
227 signal(SIGINT,lethal_signal_handler); 228 signal(SIGINT,lethal_signal_handler);
228 signal(SIGABRT,lethal_signal_handler); 229 signal(SIGABRT,lethal_signal_handler);
229 signal(SIGTERM,lethal_signal_handler); 230 signal(SIGTERM,lethal_signal_handler);
230 signal(SIGHUP,sighup_handler); 231 signal(SIGHUP,sighup_handler);
231 sigset_t sset; 232 sigset_t sset;
232 sigemptyset(&sset); 233 sigemptyset(&sset);
233 sigaddset(&sset,SIGINT); sigaddset(&sset,SIGABRT); 234 sigaddset(&sset,SIGINT); sigaddset(&sset,SIGABRT);
234 sigaddset(&sset,SIGTERM); sigaddset(&sset,SIGHUP); 235 sigaddset(&sset,SIGTERM); sigaddset(&sset,SIGHUP);
235 sigprocmask(SIG_UNBLOCK,&sset,NULL); 236 sigprocmask(SIG_UNBLOCK,&sset,NULL);
236 while(!finishing) { 237 while(!finishing) {
237 check_herd(config); 238 check_herd(config);
238 sleep(config.check_interval); 239 sleep(config.check_interval);
239 } 240 }
241 if(restarting)
242 execvp(_argv[0],_argv);
240 } 243 }
241 break; 244 break;
242 default: 245 default:
243 throw runtime_error(string(__PRETTY_FUNCTION__)+": internal error"); 246 throw runtime_error(string(__PRETTY_FUNCTION__)+": internal error");
244 } 247 }
245 }catch(exception& e) { 248 }catch(exception& e) {
246 cerr << "Oops: " << e.what() << endl; 249 cerr << "Oops: " << e.what() << endl;
247 return 1; 250 return 1;
248 } 251 }
249} 252}