summaryrefslogtreecommitdiffabout
path: root/src/genrc.c
Side-by-side diff
Diffstat (limited to 'src/genrc.c') (more/less context) (ignore whitespace changes)
-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
@@ -22,32 +22,36 @@ int genrc_verbose;
enum {
OPT_USAGE = 256,
OPT_VERSION,
OPT_SIGNAL_RELOAD,
OPT_NO_RELOAD,
OPT_SIGNAL_STOP,
- OPT_CREATE_PIDFILE
+ OPT_CREATE_PIDFILE,
+ OPT_RESTART_ON_EXIT,
+ OPT_RESTART_ON_SIGNAL,
};
struct option longopts[] = {
- { "help", no_argument, 0, 'h' },
- { "usage", no_argument, 0, OPT_USAGE },
- { "command", required_argument, 0, 'c' },
- { "program", required_argument, 0, 'p' },
- { "pid-from", required_argument, 0, 'P' },
- { "pidfile", required_argument, 0, 'F' },
- { "timeout", required_argument, 0, 't' },
- { "signal-reload", required_argument, 0, OPT_SIGNAL_RELOAD },
- { "no-reload", no_argument, 0, OPT_NO_RELOAD },
- { "signal-stop", required_argument, 0, OPT_SIGNAL_STOP },
- { "sentinel", no_argument, 0, 'S' },
- { "create-pidfile", required_argument, 0, OPT_CREATE_PIDFILE },
- { "version", no_argument, 0, OPT_VERSION },
- { "verbose", no_argument, 0, 'v' },
- { "user", required_argument, 0, 'u' },
- { "group", required_argument, 0, 'g' },
+ { "help", no_argument, 0, 'h' },
+ { "usage", no_argument, 0, OPT_USAGE },
+ { "command", required_argument, 0, 'c' },
+ { "program", required_argument, 0, 'p' },
+ { "pid-from", required_argument, 0, 'P' },
+ { "pidfile", required_argument, 0, 'F' },
+ { "timeout", required_argument, 0, 't' },
+ { "signal-reload", required_argument, 0, OPT_SIGNAL_RELOAD },
+ { "no-reload", no_argument, 0, OPT_NO_RELOAD },
+ { "signal-stop", required_argument, 0, OPT_SIGNAL_STOP },
+ { "sentinel", no_argument, 0, 'S' },
+ { "create-pidfile", required_argument, 0, OPT_CREATE_PIDFILE },
+ { "version", no_argument, 0, OPT_VERSION },
+ { "verbose", no_argument, 0, 'v' },
+ { "user", required_argument, 0, 'u' },
+ { "group", required_argument, 0, 'g' },
+ { "restart-on-exit", required_argument, 0, OPT_RESTART_ON_EXIT },
+ { "restart-on-signal", required_argument, 0, OPT_RESTART_ON_SIGNAL },
{ NULL }
};
char shortopts[] = "c:hF:g:P:p:St:u:v";
struct sigdefn {
char const *sig_name;
@@ -124,22 +128,28 @@ is_numeric_str(char const *s)
s++;
}
return 1;
}
int
-sig_name_to_str(char const *s)
+str_to_int(char const *s)
+{
+ char *end;
+ unsigned long n;
+ errno = 0;
+ n = strtoul(s, &end, 10);
+ if (errno || *end || n > UINT_MAX)
+ return -1;
+ return n;
+}
+
+int
+str_to_sig(char const *s)
{
if (is_numeric_str(s)) {
- char *end;
- unsigned long n;
- errno = 0;
- n = strtoul(s, &end, 10);
- if (errno || *end || n > UINT_MAX)
- return -1;
- return n;
+ return str_to_int(s);
} else {
struct sigdefn *sd;
for (sd = sigdefn; sd->sig_name; sd++) {
if (s[0] == 's' || s[0] == 'S') {
if (strcasecmp(sd->sig_name, s) == 0)
@@ -180,23 +190,32 @@ char const *help_msg[] = {
" run with this group(s) privileges",
"",
"Additional configuration:",
"",
" -t, --timeout=SECONDS time to wait for the program to start up or",
" terminate",
- " --sentinel PROGRAM runs in foreground; disconnect from the",
- " controlling terminal, run it and act as a sentinel",
" -P, --pid-from=SOURCE where to look for PIDs of the running programs",
" -F, --pidfile=NAME name of the PID file",
" (same as --pid-from=FILE:NAME)",
" --signal-reload=SIG signal to send on reload (default: SIGHUP)",
" setting to 0 is equivalent to --no-reload",
" --no-reload makes reload equivalent to restart",
" --signal-stop=SIG signal to send in order to terminate the program",
" (default: SIGTERM)",
"",
+ "Sentinel mode:",
+ "",
+ " --sentinel PROGRAM runs in foreground; disconnect from the",
+ " controlling terminal, run it and act as a sentinel",
+ " --restart-on-exit=[!]CODE[,...]",
+ " restart the program if it exits with one of the",
+ " listed status codes",
+ " --restart-on-signal=[!]SIG[,...]",
+ " restart the program if it terminates on one of the",
+ " listed signals",
+ "",
"Informational options:",
"",
" -h, --help display this help list",
" --usage display short usage information",
" --version display program version and exist",
"",
@@ -269,12 +288,14 @@ char const *usage_msg[] = {
"[--group GROUP[,GROUP...]]",
"[--help]",
"[--no-reload]",
"[--pid-from=SOURCE]",
"[--pidfile=PIDFILE]",
"[--program=PROGRAM]",
+ "[--restart-on-exit=[!]CODE[,...]]",
+ "[--restart-on-signal=[!]SIG[,...]]",
"[--sentinel]",
"[--signal-reload=SIG]",
"[--signal-stop=SIG]",
"[--timeout=SECONDS]",
"[--usage]",
"[--user=USER]",
@@ -419,12 +440,18 @@ main(int argc, char **argv)
case 't':
setenv("GENRC_TIMEOUT", optarg, 1);
break;
case 'S':
setenv("GENRC_SENTINEL", "1", 1);
break;
+ case OPT_RESTART_ON_EXIT:
+ add_restart_condition(RESTART_ON_EXIT, optarg);
+ break;
+ case OPT_RESTART_ON_SIGNAL:
+ add_restart_condition(RESTART_ON_SIGNAL, optarg);
+ break;
case OPT_NO_RELOAD:
no_reload = 1;
break;
case OPT_SIGNAL_RELOAD:
setenv("GENRC_SIGNAL_RELOAD", optarg, 1);
break;
@@ -447,21 +474,21 @@ main(int argc, char **argv)
if ((p = getenv("GENRC_PROGRAM")) != NULL)
genrc_program = p;
if (no_reload)
genrc_no_reload = 1;
else if ((p = getenv("GENRC_SIGNAL_RELOAD")) != NULL) {
- genrc_signal_reload = sig_name_to_str(p);
+ genrc_signal_reload = str_to_sig(p);
if (genrc_signal_reload == -1)
usage_error("%s: invalid signal number", p);
else if (genrc_signal_reload == 0)
genrc_no_reload = 1;
}
if ((p = getenv("GENRC_SIGNAL_STOP")) != NULL) {
- genrc_signal_stop = sig_name_to_str(p);
+ genrc_signal_stop = str_to_sig(p);
if (genrc_signal_stop <= 0)
usage_error("%s: invalid signal number", p);
}
if ((p = getenv("GENRC_TIMEOUT")) != NULL) {
char *end;

Return to:

Send suggestions and report system problems to the System administrator.