summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c72
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;
+}