summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--initd/main.c10
-rw-r--r--lib/include/service.h2
-rw-r--r--lib/src/rdsvc.c28
3 files changed, 40 insertions, 0 deletions
diff --git a/initd/main.c b/initd/main.c
index efd3a30..9ce23c0 100644
--- a/initd/main.c
+++ b/initd/main.c
@@ -43,6 +43,16 @@ static void handle_exited(service_t *svc)
break;
}
+ if (svc->rspwn_limit > 0) {
+ svc->rspwn_limit -= 1;
+
+ if (svc->rspwn_limit == 0) {
+ print_status(svc->desc, STATUS_FAIL, false);
+ delsvc(svc);
+ break;
+ }
+ }
+
svc->pid = runlst(svc->exec, svc->num_exec, svc->ctty);
if (svc->pid == -1) {
print_status(svc->desc, STATUS_FAIL, false);
diff --git a/lib/include/service.h b/lib/include/service.h
index 28d73f1..76d48ce 100644
--- a/lib/include/service.h
+++ b/lib/include/service.h
@@ -53,6 +53,8 @@ typedef struct service_t {
size_t num_exec; /* number of command lines */
char *ctty; /* controlling tty or log file */
+ int rspwn_limit; /* maximum respawn count */
+
char **before; /* services that must be executed later */
size_t num_before;
char **after; /* services that must be executed first */
diff --git a/lib/src/rdsvc.c b/lib/src/rdsvc.c
index 972f7e4..54c6d24 100644
--- a/lib/src/rdsvc.c
+++ b/lib/src/rdsvc.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
+#include <ctype.h>
#include "service.h"
#include "util.h"
@@ -132,6 +133,32 @@ static int svc_target(service_t *svc, char *arg,
return 0;
}
+static int svc_rspwn_limit(service_t *svc, char *arg,
+ const char *filename, size_t lineno)
+{
+ const char *ptr;
+
+ svc->rspwn_limit = 0;
+
+ if (!isdigit(*arg))
+ goto fail;
+
+ for (ptr = arg; isdigit(*ptr); ++ptr)
+ svc->rspwn_limit = svc->rspwn_limit * 10 + (*ptr - '0');
+
+ if (*ptr != '\0')
+ goto fail;
+
+ free(arg);
+ return 0;
+fail:
+ fprintf(stderr,
+ "%s: %zu: expected numeric argument for respawn limit\n",
+ filename, lineno);
+ free(arg);
+ return -1;
+}
+
static const struct {
const char *key;
@@ -147,6 +174,7 @@ static const struct {
{ "tty", svc_tty },
{ "before", svc_before },
{ "after", svc_after },
+ { "respawn_limit", svc_rspwn_limit },
};