diff options
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..772dbf8 --- /dev/null +++ b/src/util.c @@ -0,0 +1,72 @@ +/* Copyright 2016 Luke Shumaker */ + +#include <ctype.h> /* for isdigit */ +#include <stdlib.h> +#include <error.h> +#include <errno.h> + +#include "util.h" + +void *xrealloc(void *ptr, size_t size) +{ + void *ret = realloc(ptr, size); + if (ret == NULL) { + if (ptr==NULL) + error(1, errno, "Could not allocate memory"); + else + error(1, errno, "Could not re-allocate memory"); + } + return ret; +} + +bool is_numeric(const char *str) { + for (size_t i = 0; str[i] != '\0'; i++) + if (!isdigit(str[i])) + return false; + if (str[0] == '\0') + return false; + return true; +} + +int get_fd(const char *addr) { + int sock; + if (strcmp(addr, "stdin") == 0) { + sock = 0; + } else if (strcmp(addr, "stdout") == 0) { + sock = 1; + } else if (strcmp(addr, "stderr") == 0) { + sock = 2; + } else if (strncmp(addr, "systemd", strlen("systemd")) == 0) { + sock = 3; /* <systemd/sd-daemon.h>:SD_LISTEN_FDS_START */ + addr = &addr[strlen("systemd")]; + switch (addr[0]) { + case '\0': + /* do nothing */ + break; + case ':': + addr = &addr[1]; + if (is_numeric(addr)) { + sock += atoi(addr); + } else { + const char *e = getenv("LISTEN_FDNAMES"); + if (e == NULL) + return -ENOTCONN; + char *names = strdupa(e); + char *name = NULL; + int i = -1; + do { + name = strsep(&names, ":"); + i++; + } while (name != NULL && strcmp(name, addr) != 0); + if (name == NULL) + return -ENOENT; + sock += i; + } + } + } else { + if (!is_numeric(addr)) + return -EINVAL; + sock = atoi(addr); + } + return sock; +} |