diff options
author | Heikki Kallasjoki <fis@zem.fi> | 2018-11-30 15:51:05 +0000 |
---|---|---|
committer | Heikki Kallasjoki <fis@zem.fi> | 2018-11-30 15:51:05 +0000 |
commit | 2c6ca9942bcecf062010c7c5e3c35e30d91f7434 (patch) | |
tree | 2093abc4dd5359b22c20b46799319c29271377b8 | |
parent | 69e51e6eec450a9e0a896d93ccdb1a92abf4ff85 (diff) | |
download | nano-exporter-2c6ca9942bcecf062010c7c5e3c35e30d91f7434.tar.gz nano-exporter-2c6ca9942bcecf062010c7c5e3c35e30d91f7434.tar.xz nano-exporter-2c6ca9942bcecf062010c7c5e3c35e30d91f7434.zip |
Daemonize to background by default.
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | main.c | 67 |
2 files changed, 65 insertions, 3 deletions
diff --git a/README.md b/README.md index 52f863d..79ef13a 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Reference](#collector-reference) section. | Flag | Description | | ---- | ----------- | +| `--foreground` | Don't daemonize, but remain on the foreground instead. | | `--port=X` | Listen on port *X* instead of the default port (9100). | ## Collector Reference diff --git a/main.c b/main.c index 08b7dab..43acbcb 100644 --- a/main.c +++ b/main.c @@ -3,7 +3,11 @@ #include <stdbool.h> #include <stddef.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> #include "collector.h" #include "scrape.h" @@ -30,6 +34,12 @@ enum tristate { flag_off = -1, flag_undef = 0, flag_on = 1 }; struct config { const char *port; + bool daemonize; +}; + +const struct config default_config = { + .port = "9100", + .daemonize = true, }; struct handler_ctx { @@ -43,12 +53,11 @@ struct handler_ctx { static bool parse_args(int argc, char *argv[], struct config *cfg, struct handler_ctx *ctx); static bool initialize(struct handler_ctx *ctx, int max_args); +static bool daemonize(void); static void handler(scrape_req *req, void *ctx_ptr); int main(int argc, char *argv[]) { - struct config cfg = { - .port = "9100", - }; + struct config cfg = default_config; struct handler_ctx ctx; if (!parse_args(argc, argv, &cfg, &ctx)) @@ -60,6 +69,10 @@ int main(int argc, char *argv[]) { if (!server) return 1; + if (cfg.daemonize) + if (!daemonize()) + return 1; + scrape_serve(server, handler, &ctx); scrape_close(server); @@ -105,6 +118,9 @@ static bool parse_args(int argc, char *argv[], struct config *cfg, struct handle if (strncmp(argv[arg], "--port=", 7) == 0) { cfg->port = &argv[arg][7]; goto next_arg; + } else if (strcmp(argv[arg], "--foreground") == 0) { + cfg->daemonize = false; + goto next_arg; } fprintf(stderr, "unknown argument: %s\n", argv[arg]); @@ -142,6 +158,51 @@ static bool initialize(struct handler_ctx *ctx, int max_args) { return true; } +static bool daemonize(void) { + pid_t pid; + + pid = fork(); + if (pid == -1) { + perror("fork"); + return false; + } + + if (pid > 0) { + // in the parent, verify the intermediate process exits successfully + int status; + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid(daemon)"); + exit(1); + } + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + fprintf(stderr, "daemonized process exited unexpectedly: %x\n", status); + exit(1); + } + exit(0); + } + + // in the intermediate process, prepare for daemon life and fork again + + if (setsid() == -1) { + perror("setsid"); + exit(1); + } + + close(0); + close(1); + close(2); + + pid = fork(); + if (pid == -1) + exit(2); + else if (pid > 0) + exit(0); // lets the parent know all is well + + // in the grandchild, continue execution + + return true; +} + static void handler(scrape_req *req, void *ctx_ptr) { struct handler_ctx *ctx = ctx_ptr; |