From 278ec70925695a7b767e2b628c67319d218c3d03 Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Mon, 19 Oct 2020 22:04:09 +0200 Subject: Added logging support (incomplete unless using noclose) --- daemonize.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 83 insertions(+), 21 deletions(-) (limited to 'daemonize.c') diff --git a/daemonize.c b/daemonize.c index 94662d6..c9c925f 100644 --- a/daemonize.c +++ b/daemonize.c @@ -1,16 +1,37 @@ #include #include #include +#include #include #include +#include + +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] "); +} + void qtoofewargs () { - q("[daemonize] Too few arguments.\nUsage: daemonize [--chdir] [--noclose] "); + 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); } -- cgit v1.2.3