summaryrefslogtreecommitdiffabout
path: root/src/dudki.cc
authorMichael Krelin <hacker@klever.net>2004-07-23 21:31:57 (UTC)
committer Michael Krelin <hacker@klever.net>2004-07-23 21:31:57 (UTC)
commit125671c860a82643d36bc3da279d0b831fae4b34 (patch) (unidiff)
treeab5edcac7c58e769c9d8436ae0e803edb2ebca9f /src/dudki.cc
parent0a7f5999eb47ce113b3cd47b03198947441945a7 (diff)
downloaddudki-125671c860a82643d36bc3da279d0b831fae4b34.zip
dudki-125671c860a82643d36bc3da279d0b831fae4b34.tar.gz
dudki-125671c860a82643d36bc3da279d0b831fae4b34.tar.bz2
ability to send arbitrary signals
Diffstat (limited to 'src/dudki.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--src/dudki.cc20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/dudki.cc b/src/dudki.cc
index e91ad5e..9562079 100644
--- a/src/dudki.cc
+++ b/src/dudki.cc
@@ -1,27 +1,28 @@
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 <errno.h>
4#include <iostream> 5#include <iostream>
5#include <fstream> 6#include <fstream>
6#include <stdexcept> 7#include <stdexcept>
7using namespace std; 8using namespace std;
8#include "configuration.h" 9#include "configuration.h"
9#include "util.h" 10#include "util.h"
10 11
11#include "config.h" 12#include "config.h"
12#ifdef HAVE_GETOPT_H 13#ifdef HAVE_GETOPT_H
13# include <getopt.h> 14# include <getopt.h>
14#endif 15#endif
15 16
16#ifndef DEFAULT_CONF_FILE 17#ifndef DEFAULT_CONF_FILE
17# define DEFAULT_CONF_FILE "/etc/dudki.conf" 18# define DEFAULT_CONF_FILE "/etc/dudki.conf"
18#endif 19#endif
19 20
20#define PHEADER PACKAGE " Version " VERSION 21#define PHEADER PACKAGE " Version " VERSION
21#define PCOPY "Copyright (c) 2004 Klever Group" 22#define PCOPY "Copyright (c) 2004 Klever Group"
22 23
23bool finishing = false; 24bool finishing = false;
24bool restarting = false; 25bool restarting = false;
25static char **_argv = NULL; 26static char **_argv = NULL;
26 27
27static void lethal_signal_handler(int signum) { 28static void lethal_signal_handler(int signum) {
@@ -47,97 +48,101 @@ void signal_self(const configuration& config,int signum) {
47 if(!pid) 48 if(!pid)
48 throw runtime_error("Can't detect running instance"); 49 throw runtime_error("Can't detect running instance");
49 if(pid==getpid()) 50 if(pid==getpid())
50 throw 0; 51 throw 0;
51 if(kill(pid,signum)) 52 if(kill(pid,signum))
52 throw runtime_error("Failed to signal running instance"); 53 throw runtime_error("Failed to signal running instance");
53} 54}
54 55
55int main(int argc,char **argv) { 56int main(int argc,char **argv) {
56 try { 57 try {
57 _argv = new char*[argc+1]; 58 _argv = new char*[argc+1];
58 if(!_argv) 59 if(!_argv)
59 throw runtime_error("memory allocation problem at the very start"); 60 throw runtime_error("memory allocation problem at the very start");
60 memmove(_argv,argv,sizeof(*_argv)*(argc+1)); 61 memmove(_argv,argv,sizeof(*_argv)*(argc+1));
61 string config_file = DEFAULT_CONF_FILE; 62 string config_file = DEFAULT_CONF_FILE;
62 enum { 63 enum {
63 op_default, 64 op_default,
64 op_work, 65 op_work,
65 op_signal, 66 op_signal,
66 op_ensure, 67 op_ensure,
67 op_test 68 op_test
68 } op = op_default; 69 } op = op_default;
69 int op_signum = 0; 70 int op_signum = 0;
70 while(true) { 71 while(true) {
71 #defineSHORTOPTSTRING "f:hVLrkcet" 72 #defineSHORTOPTSTRING "f:hVLrkcets:"
72#ifdef HAVE_GETOPT_LONG 73#ifdef HAVE_GETOPT_LONG
73 static struct option opts[] = { 74 static struct option opts[] = {
74 { "help", no_argument, 0, 'h' }, 75 { "help", no_argument, 0, 'h' },
75 { "usage", no_argument, 0, 'h' }, 76 { "usage", no_argument, 0, 'h' },
76 { "version", no_argument, 0, 'V' }, 77 { "version", no_argument, 0, 'V' },
77 { "license", no_argument, 0, 'L' }, 78 { "license", no_argument, 0, 'L' },
78 { "config", required_argument, 0, 'f' }, 79 { "config", required_argument, 0, 'f' },
79 { "kill", no_argument, 0, 'k' }, 80 { "kill", no_argument, 0, 'k' },
80 { "reload", no_argument, 0, 'r' }, 81 { "reload", no_argument, 0, 'r' },
82 { "signal", required_argument, 0, 's' },
81 { "check", no_argument, 0, 'c' }, 83 { "check", no_argument, 0, 'c' },
82 { "ensure", no_argument, 0, 'e' }, 84 { "ensure", no_argument, 0, 'e' },
83 { "test", no_argument, 0, 't' }, 85 { "test", no_argument, 0, 't' },
84 { NULL, 0, 0, 0 } 86 { NULL, 0, 0, 0 }
85 }; 87 };
86 int c = getopt_long(argc,argv,SHORTOPTSTRING,opts,NULL); 88 int c = getopt_long(argc,argv,SHORTOPTSTRING,opts,NULL);
87#else /* !HAVE_GETOPT_LONG */ 89#else /* !HAVE_GETOPT_LONG */
88 int c = getopt(argc,argv,SHORTOPTSTRING); 90 int c = getopt(argc,argv,SHORTOPTSTRING);
89#endif /* /HAVE_GETOPT_LONG */ 91#endif /* /HAVE_GETOPT_LONG */
90 if(c==-1) 92 if(c==-1)
91 break; 93 break;
92 switch(c) { 94 switch(c) {
93 case 'h': 95 case 'h':
94 cerr << PHEADER << endl 96 cerr << PHEADER << endl
95 << PCOPY << endl << endl 97 << PCOPY << endl << endl
96 << " " << argv[0] << " [options] [processes]" << endl << endl << 98 << " " << argv[0] << " [options] [processes]" << endl << endl <<
97#ifdef HAVE_GETOPT_LONG 99#ifdef HAVE_GETOPT_LONG
98 " -h, --help\n" 100 " -h, --help\n"
99 " --usage display this text\n" 101 " --usage display this text\n"
100 " -V, --version display version number\n" 102 " -V, --version display version number\n"
101 " -L, --license show license\n" 103 " -L, --license show license\n"
102 " -f filename, --config=filename\n" 104 " -f filename, --config=filename\n"
103 " specify the configuration file to use\n" 105 " specify the configuration file to use\n"
104 "\n" 106 "\n"
105 " -k, --kill stop running instance (send SIGTERM)\n" 107 " -k, --kill stop running instance (send SIGTERM)\n"
106 " -r, --reload reload running instance (send SIGHUP)\n" 108 " -r, --reload reload running instance (send SIGHUP)\n"
109 " -s signum, --signal=signum\n"
110 " send the specified signal to the running process\n"
107 " -c, --check check if the process is running\n" 111 " -c, --check check if the process is running\n"
108 " (the above commands operate on dudki itself if no\n" 112 " (the above commands operate on dudki itself if no\n"
109 " process name has been specified)\n" 113 " process name has been specified)\n"
110 " -e, --ensure ensure that dudki is running\n" 114 " -e, --ensure ensure that dudki is running\n"
111 " -t, --test test configuration file and exit" 115 " -t, --test test configuration file and exit"
112#else /* !HAVE_GETOPT_LONG */ 116#else /* !HAVE_GETOPT_LONG */
113 " -h display this text\n" 117 " -h display this text\n"
114 " -V display version number\n" 118 " -V display version number\n"
115 " -L show license\n" 119 " -L show license\n"
116 " -f filename specify the configuration file to use\n" 120 " -f filename specify the configuration file to use\n"
117 "\n" 121 "\n"
118 " -k stop running instance (send SIGTERM)\n" 122 " -k stop running instance (send SIGTERM)\n"
119 " -r reload running instance (send SIGHUP)\n" 123 " -r reload running instance (send SIGHUP)\n"
124 " -s signum send the specified signal to the running process\n"
120 " -c check if the process is running\n" 125 " -c check if the process is running\n"
121 " (the above commands operate on dudki itself if no\n" 126 " (the above commands operate on dudki itself if no\n"
122 " process name has been specified)\n" 127 " process name has been specified)\n"
123 " -e ensure that dudki is running\n" 128 " -e ensure that dudki is running\n"
124 " -t test configuration file and exit" 129 " -t test configuration file and exit"
125#endif /* /HAVE_GETOPT_LONG */ 130#endif /* /HAVE_GETOPT_LONG */
126 << endl; 131 << endl;
127 exit(0); 132 exit(0);
128 break; 133 break;
129 case 'V': 134 case 'V':
130 cerr << VERSION << endl; 135 cerr << VERSION << endl;
131 exit(0); 136 exit(0);
132 break; 137 break;
133 case 'L': 138 case 'L':
134 extern const char *COPYING; 139 extern const char *COPYING;
135 cerr << COPYING << endl; 140 cerr << COPYING << endl;
136 exit(0); 141 exit(0);
137 break; 142 break;
138 case 'f': 143 case 'f':
139 config_file = optarg; 144 config_file = optarg;
140 break; 145 break;
141 case 'k': 146 case 'k':
142 if(op!=op_default) { 147 if(op!=op_default) {
143 cerr << "Can't obey two or more orders at once" << endl; 148 cerr << "Can't obey two or more orders at once" << endl;
@@ -152,48 +157,61 @@ int main(int argc,char **argv) {
152 } 157 }
153 op = op_signal; op_signum = SIGHUP; 158 op = op_signal; op_signum = SIGHUP;
154 break; 159 break;
155 case 'c': 160 case 'c':
156 if(op!=op_default) { 161 if(op!=op_default) {
157 cerr << "Can't obey two or more orders at once" << endl; 162 cerr << "Can't obey two or more orders at once" << endl;
158 exit(1); 163 exit(1);
159 } 164 }
160 op = op_signal; op_signum = 0; 165 op = op_signal; op_signum = 0;
161 break; 166 break;
162 case 'e': 167 case 'e':
163 if(op!=op_default) { 168 if(op!=op_default) {
164 cerr << "Can't obey two or more orders at once" << endl; 169 cerr << "Can't obey two or more orders at once" << endl;
165 exit(1); 170 exit(1);
166 } 171 }
167 op = op_ensure; 172 op = op_ensure;
168 break; 173 break;
169 case 't': 174 case 't':
170 if(op!=op_default) { 175 if(op!=op_default) {
171 cerr << "Can't obey two or more orders at once" << endl; 176 cerr << "Can't obey two or more orders at once" << endl;
172 exit(1); 177 exit(1);
173 } 178 }
174 op = op_test; 179 op = op_test;
175 break; 180 break;
181 case 's':
182 if(op!=op_default) {
183 cerr << "Can't obey two or more orders at once" << endl;
184 exit(1);
185 }
186 op = op_signal;
187 errno = 0;
188 op_signum = strtol(optarg,NULL,0);
189 if(errno) {
190 cerr << "Can't obtain the signal value" << endl;
191 exit(1);
192 }
193 break;
176 default: 194 default:
177 cerr << "Huh??" << endl; 195 cerr << "Huh??" << endl;
178 exit(1); 196 exit(1);
179 break; 197 break;
180 } 198 }
181 } 199 }
182 const char *sid = *argv; 200 const char *sid = *argv;
183 const char *t; 201 const char *t;
184 while(t = index(sid,'/')) { 202 while(t = index(sid,'/')) {
185 sid = t; sid++; 203 sid = t; sid++;
186 } 204 }
187 openlog(sid,LOG_CONS|LOG_PERROR|LOG_PID,LOG_DAEMON); 205 openlog(sid,LOG_CONS|LOG_PERROR|LOG_PID,LOG_DAEMON);
188 configuration config; 206 configuration config;
189 config.parse(config_file); 207 config.parse(config_file);
190 switch(op) { 208 switch(op) {
191 case op_test: 209 case op_test:
192 cerr << "Configuration OK" << endl; 210 cerr << "Configuration OK" << endl;
193 break; 211 break;
194 case op_signal: 212 case op_signal:
195 try { 213 try {
196 if(optind>=argc) { 214 if(optind>=argc) {
197 signal_self(config,op_signum); 215 signal_self(config,op_signum);
198 }else{ 216 }else{
199 int failures = 0; 217 int failures = 0;