aboutsummaryrefslogtreecommitdiff
path: root/src/genrc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/genrc.c')
-rw-r--r--src/genrc.c85
1 files changed, 56 insertions, 29 deletions
diff --git a/src/genrc.c b/src/genrc.c
index ae3070d..9052987 100644
--- a/src/genrc.c
+++ b/src/genrc.c
@@ -16,44 +16,48 @@ int genrc_signal_stop = SIGTERM;
16int genrc_signal_reload = SIGHUP; 16int genrc_signal_reload = SIGHUP;
17GENRC_PID_CLOSURE *genrc_pid_closure; 17GENRC_PID_CLOSURE *genrc_pid_closure;
18char *genrc_create_pidfile; 18char *genrc_create_pidfile;
19int genrc_verbose; 19int genrc_verbose;
20 20
21 21
22enum { 22enum {
23 OPT_USAGE = 256, 23 OPT_USAGE = 256,
24 OPT_VERSION, 24 OPT_VERSION,
25 OPT_SIGNAL_RELOAD, 25 OPT_SIGNAL_RELOAD,
26 OPT_NO_RELOAD, 26 OPT_NO_RELOAD,
27 OPT_SIGNAL_STOP, 27 OPT_SIGNAL_STOP,
28 OPT_CREATE_PIDFILE 28 OPT_CREATE_PIDFILE,
29 OPT_RESTART_ON_EXIT,
30 OPT_RESTART_ON_SIGNAL,
29}; 31};
30 32
31struct option longopts[] = { 33struct option longopts[] = {
32 { "help", no_argument, 0, 'h' }, 34 { "help", no_argument, 0, 'h' },
33 { "usage", no_argument, 0, OPT_USAGE }, 35 { "usage", no_argument, 0, OPT_USAGE },
34 { "command", required_argument, 0, 'c' }, 36 { "command", required_argument, 0, 'c' },
35 { "program", required_argument, 0, 'p' }, 37 { "program", required_argument, 0, 'p' },
36 { "pid-from", required_argument, 0, 'P' }, 38 { "pid-from", required_argument, 0, 'P' },
37 { "pidfile", required_argument, 0, 'F' }, 39 { "pidfile", required_argument, 0, 'F' },
38 { "timeout", required_argument, 0, 't' }, 40 { "timeout", required_argument, 0, 't' },
39 { "signal-reload", required_argument, 0, OPT_SIGNAL_RELOAD }, 41 { "signal-reload", required_argument, 0, OPT_SIGNAL_RELOAD },
40 { "no-reload", no_argument, 0, OPT_NO_RELOAD }, 42 { "no-reload", no_argument, 0, OPT_NO_RELOAD },
41 { "signal-stop", required_argument, 0, OPT_SIGNAL_STOP }, 43 { "signal-stop", required_argument, 0, OPT_SIGNAL_STOP },
42 { "sentinel", no_argument, 0, 'S' }, 44 { "sentinel", no_argument, 0, 'S' },
43 { "create-pidfile", required_argument, 0, OPT_CREATE_PIDFILE }, 45 { "create-pidfile", required_argument, 0, OPT_CREATE_PIDFILE },
44 { "version", no_argument, 0, OPT_VERSION }, 46 { "version", no_argument, 0, OPT_VERSION },
45 { "verbose", no_argument, 0, 'v' }, 47 { "verbose", no_argument, 0, 'v' },
46 { "user", required_argument, 0, 'u' }, 48 { "user", required_argument, 0, 'u' },
47 { "group", required_argument, 0, 'g' }, 49 { "group", required_argument, 0, 'g' },
50 { "restart-on-exit", required_argument, 0, OPT_RESTART_ON_EXIT },
51 { "restart-on-signal", required_argument, 0, OPT_RESTART_ON_SIGNAL },
48 { NULL } 52 { NULL }
49}; 53};
50char shortopts[] = "c:hF:g:P:p:St:u:v"; 54char shortopts[] = "c:hF:g:P:p:St:u:v";
51 55
52struct sigdefn { 56struct sigdefn {
53 char const *sig_name; 57 char const *sig_name;
54 int sig_no; 58 int sig_no;
55}; 59};
56 60
57#define S(s) { #s, s } 61#define S(s) { #s, s }
58static struct sigdefn sigdefn[] = { 62static struct sigdefn sigdefn[] = {
59 S (SIGHUP), 63 S (SIGHUP),
@@ -118,34 +122,40 @@ static struct sigdefn sigdefn[] = {
118static int 122static int
119is_numeric_str(char const *s) 123is_numeric_str(char const *s)
120{ 124{
121 while (*s) { 125 while (*s) {
122 if (!isdigit(*s)) 126 if (!isdigit(*s))
123 return 0; 127 return 0;
124 s++; 128 s++;
125 } 129 }
126 return 1; 130 return 1;
127} 131}
128 132
129int 133int
130sig_name_to_str(char const *s) 134str_to_int(char const *s)
135{
136 char *end;
137 unsigned long n;
138 errno = 0;
139 n = strtoul(s, &end, 10);
140 if (errno || *end || n > UINT_MAX)
141 return -1;
142 return n;
143}
144
145int
146str_to_sig(char const *s)
131{ 147{
132 if (is_numeric_str(s)) { 148 if (is_numeric_str(s)) {
133 char *end; 149 return str_to_int(s);
134 unsigned long n;
135 errno = 0;
136 n = strtoul(s, &end, 10);
137 if (errno || *end || n > UINT_MAX)
138 return -1;
139 return n;
140 } else { 150 } else {
141 struct sigdefn *sd; 151 struct sigdefn *sd;
142 152
143 for (sd = sigdefn; sd->sig_name; sd++) { 153 for (sd = sigdefn; sd->sig_name; sd++) {
144 if (s[0] == 's' || s[0] == 'S') { 154 if (s[0] == 's' || s[0] == 'S') {
145 if (strcasecmp(sd->sig_name, s) == 0) 155 if (strcasecmp(sd->sig_name, s) == 0)
146 return sd->sig_no; 156 return sd->sig_no;
147 } else if (strcasecmp(sd->sig_name + 3, s) == 0) 157 } else if (strcasecmp(sd->sig_name + 3, s) == 0)
148 return sd->sig_no; 158 return sd->sig_no;
149 } 159 }
150 } 160 }
151 return -1; 161 return -1;
@@ -174,35 +184,44 @@ char const *help_msg[] = {
174 " first word (in the shell sense) in COMMAND.", 184 " first word (in the shell sense) in COMMAND.",
175 "", 185 "",
176 "Runtime privileges:", 186 "Runtime privileges:",
177 "", 187 "",
178 " -u, --user=NAME run with this user privileges", 188 " -u, --user=NAME run with this user privileges",
179 " -g, --group=GROUP[,GROUP...]]", 189 " -g, --group=GROUP[,GROUP...]]",
180 " run with this group(s) privileges", 190 " run with this group(s) privileges",
181 "", 191 "",
182 "Additional configuration:", 192 "Additional configuration:",
183 "", 193 "",
184 " -t, --timeout=SECONDS time to wait for the program to start up or", 194 " -t, --timeout=SECONDS time to wait for the program to start up or",
185 " terminate", 195 " terminate",
186 " --sentinel PROGRAM runs in foreground; disconnect from the",
187 " controlling terminal, run it and act as a sentinel",
188 " -P, --pid-from=SOURCE where to look for PIDs of the running programs", 196 " -P, --pid-from=SOURCE where to look for PIDs of the running programs",
189 " -F, --pidfile=NAME name of the PID file", 197 " -F, --pidfile=NAME name of the PID file",
190 " (same as --pid-from=FILE:NAME)", 198 " (same as --pid-from=FILE:NAME)",
191 " --signal-reload=SIG signal to send on reload (default: SIGHUP)", 199 " --signal-reload=SIG signal to send on reload (default: SIGHUP)",
192 " setting to 0 is equivalent to --no-reload", 200 " setting to 0 is equivalent to --no-reload",
193 " --no-reload makes reload equivalent to restart", 201 " --no-reload makes reload equivalent to restart",
194 " --signal-stop=SIG signal to send in order to terminate the program", 202 " --signal-stop=SIG signal to send in order to terminate the program",
195 " (default: SIGTERM)", 203 " (default: SIGTERM)",
196 "", 204 "",
205 "Sentinel mode:",
206 "",
207 " --sentinel PROGRAM runs in foreground; disconnect from the",
208 " controlling terminal, run it and act as a sentinel",
209 " --restart-on-exit=[!]CODE[,...]",
210 " restart the program if it exits with one of the",
211 " listed status codes",
212 " --restart-on-signal=[!]SIG[,...]",
213 " restart the program if it terminates on one of the",
214 " listed signals",
215 "",
197 "Informational options:", 216 "Informational options:",
198 "", 217 "",
199 " -h, --help display this help list", 218 " -h, --help display this help list",
200 " --usage display short usage information", 219 " --usage display short usage information",
201 " --version display program version and exist", 220 " --version display program version and exist",
202 "", 221 "",
203 "Influential environment variables and corresponding options:", 222 "Influential environment variables and corresponding options:",
204 "", 223 "",
205 " GENRC_COMMAND=COMMAND --command=COMMAND", 224 " GENRC_COMMAND=COMMAND --command=COMMAND",
206 " GENRC_PROGRAM=NAME --program=NAME", 225 " GENRC_PROGRAM=NAME --program=NAME",
207 " GENRC_PID_FROM=SOURCE --pid-from=SOURCE", 226 " GENRC_PID_FROM=SOURCE --pid-from=SOURCE",
208 " GENRC_TIMEOUT=SECONDS --timeout=SECONDS", 227 " GENRC_TIMEOUT=SECONDS --timeout=SECONDS",
@@ -263,24 +282,26 @@ char const *usage_msg[] = {
263 "[-c COMMAND]", 282 "[-c COMMAND]",
264 "[-g GROUP[,GROUP...]]", 283 "[-g GROUP[,GROUP...]]",
265 "[-p PROGRAM]", 284 "[-p PROGRAM]",
266 "[-t SECONDS]", 285 "[-t SECONDS]",
267 "[-u USER]", 286 "[-u USER]",
268 "[--command=COMMAND]", 287 "[--command=COMMAND]",
269 "[--group GROUP[,GROUP...]]", 288 "[--group GROUP[,GROUP...]]",
270 "[--help]", 289 "[--help]",
271 "[--no-reload]", 290 "[--no-reload]",
272 "[--pid-from=SOURCE]", 291 "[--pid-from=SOURCE]",
273 "[--pidfile=PIDFILE]", 292 "[--pidfile=PIDFILE]",
274 "[--program=PROGRAM]", 293 "[--program=PROGRAM]",
294 "[--restart-on-exit=[!]CODE[,...]]",
295 "[--restart-on-signal=[!]SIG[,...]]",
275 "[--sentinel]", 296 "[--sentinel]",
276 "[--signal-reload=SIG]", 297 "[--signal-reload=SIG]",
277 "[--signal-stop=SIG]", 298 "[--signal-stop=SIG]",
278 "[--timeout=SECONDS]", 299 "[--timeout=SECONDS]",
279 "[--usage]", 300 "[--usage]",
280 "[--user=USER]", 301 "[--user=USER]",
281 "{", 302 "{",
282 "start", 303 "start",
283 "|", 304 "|",
284 "stop", 305 "stop",
285 "|", 306 "|",
286 "restart", 307 "restart",
@@ -413,24 +434,30 @@ main(int argc, char **argv)
413 case 'g': 434 case 'g':
414 setenv("GENRC_GROUP", optarg, 1); 435 setenv("GENRC_GROUP", optarg, 1);
415 break; 436 break;
416 case OPT_CREATE_PIDFILE: 437 case OPT_CREATE_PIDFILE: