diff options
| author | Carson Fleming <cflems@cflems.net> | 2020-10-19 22:04:09 +0200 |
|---|---|---|
| committer | Carson Fleming <cflems@cflems.net> | 2020-10-19 22:04:09 +0200 |
| commit | 278ec70925695a7b767e2b628c67319d218c3d03 (patch) | |
| tree | abc736ce4f7380170c568ae79212cd286e573030 | |
| parent | 2826c6082ba0d0d3c006b48c0ae76b32f29093dc (diff) | |
| download | daemonize-278ec70925695a7b767e2b628c67319d218c3d03.tar.gz | |
Added logging support (incomplete unless using noclose)
| -rwxr-xr-x | daemonize | bin | 0 -> 17968 bytes | |||
| -rw-r--r-- | daemonize.c | 104 |
2 files changed, 83 insertions, 21 deletions
diff --git a/daemonize b/daemonize Binary files differnew file mode 100755 index 0000000..d75d6bc --- /dev/null +++ b/daemonize diff --git a/daemonize.c b/daemonize.c index 94662d6..c9c925f 100644 --- a/daemonize.c +++ b/daemonize.c @@ -1,16 +1,37 @@ #include <stdlib.h> #include <stdio.h> #include <unistd.h> +#include <getopt.h> #include <ctype.h> #include <string.h> +#include <stdbool.h> + +const struct option longopts[] = { + {"chdir", no_argument, NULL, 'd'}, + {"noclose", no_argument, NULL, 'n'}, + {"log-stdout", required_argument, NULL, '1'}, + {"log-stderr", required_argument, NULL, '2'}, + {0, 0, 0, 0} +}; +const char* optstring = "dn1:2:"; void q (char* m) { fprintf(stderr, "%s\n", m); exit(1); } +void qusage () { + q("[daemonize] Usage: daemonize [-d|--chdir] [-n|--noclose] [-1|--log-stdout /path/to/log] [-2|--log-stderr /path/to/log] <command>"); +} + void qtoofewargs () { - q("[daemonize] Too few arguments.\nUsage: daemonize [--chdir] [--noclose] <command>"); + fprintf(stderr, "[daemonize] Too few arguments.\n"); + qusage(); +} + +void qinvalidarg (char* arg) { + fprintf(stderr, "[daemonize] Unrecognized argument: %s\n", arg); + qusage(); } char* lowerdup (char* a) { @@ -22,32 +43,73 @@ char* lowerdup (char* a) { return b; } -int main (int argc, char** argv) { +struct opts { + int nochdir; + int noclose; + FILE* stdlog; + FILE* errlog; +}; + +void parseargs(int argc, char** argv, struct opts* savedopts) { if (argc < 2) qtoofewargs(); - int i, cmdlen = 0, buff_size = 256, nochdir = 1, noclose = 0; + int c; + + while ((c = getopt_long(argc, argv, optstring, longopts, NULL)) != -1) { + switch (c) { + case 'd': + savedopts->nochdir = false; + break; + case 'n': + savedopts->noclose = true; + break; + case '1': + savedopts->stdlog = fopen(optarg, "a"); + if (!savedopts->stdlog) q("[daemonize] Unable to open stdout log, quitting."); + break; + case '2': + savedopts->errlog = fopen(optarg, "a"); + if (!savedopts->errlog) q("[daemonize] Unable to open stderr log, quitting."); + break; + default: + // just let getopt print the error + break; + } + } +} + +int main (int argc, char** argv) { + struct opts options = {true, false, NULL, NULL}; + parseargs(argc, argv, &options); + + int cmdlen = 0, buff_size = 256; char* buffer = malloc(buff_size); - - for (i = 1; i < argc; i++) { - char* cmp = lowerdup(argv[i]); - if (strcmp(cmp, "--chdir") == 0) nochdir = 0; - else if (strcmp(cmp, "--noclose") == 0) noclose = 1; - else { - int arglen = strlen(argv[i]); - if (cmdlen+arglen+1 > buff_size) { - buff_size *= 2; - buffer = realloc(buffer, buff_size); - if (buffer == NULL) q("[daemonize] Out of memory parsing arguments."); - } - strncpy(&buffer[cmdlen], argv[i], arglen); - cmdlen += arglen+1; - buffer[cmdlen-1] = ' '; + + while (optind < argc) { + int arglen = strlen(argv[optind]); + if (cmdlen+arglen+1 > buff_size) { + buff_size *= 2; + buffer = realloc(buffer, buff_size); + if (buffer == NULL) q("[daemonize] Out of memory parsing arguments."); } - free(cmp); + strncpy(&buffer[cmdlen], argv[optind++], arglen); + cmdlen += arglen+1; + buffer[cmdlen-1] = ' '; } buffer[cmdlen-1] = 0; - + if (cmdlen < 1) qtoofewargs(); - daemon(nochdir, noclose); + // Set up logs as appropriate + int logs = options.stdlog || options.errlog; + if (options.stdlog) { + dup2(fileno(options.stdlog), fileno(stdout)); + fclose(options.stdlog); + } + if (options.errlog) { + dup2(fileno(options.errlog), fileno(stderr)); + fclose(options.errlog); + } + // TODO: close stdin, stderr, stdout and redirect to /dev/null if logging + daemon(options.nochdir, options.noclose | logs); system(buffer); } |
