From 29bec0c0e0658b51f11ea38c04df0e7aa514572c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Sun, 26 Oct 2014 18:57:28 +0100 Subject: Lay down some server-client foundations --- utils.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'utils.c') diff --git a/utils.c b/utils.c index 27d9e8d..e1580e0 100644 --- a/utils.c +++ b/utils.c @@ -34,6 +34,9 @@ #define N_ELEMENTS(a) (sizeof (a) / sizeof ((a)[0])) +#define BLOCK_START do { +#define BLOCK_END } while (0) + // --- Safe memory management -------------------------------------------------- // When a memory allocation fails and we need the memory, we're usually pretty @@ -76,6 +79,31 @@ xrealloc (void *o, size_t n) return p; } +// --- Double-linked list helpers ---------------------------------------------- + +#define LIST_HEADER(type) \ + type *next; \ + type *prev; + +#define LIST_PREPEND(head, link) \ + BLOCK_START \ + (link)->prev = NULL; \ + (link)->next = (head); \ + if ((link)->next) \ + (link)->next->prev = (link); \ + (head) = (link); \ + BLOCK_END + +#define LIST_UNLINK(head, link) \ + BLOCK_START \ + if ((link)->prev) \ + (link)->prev->next = (link)->next; \ + else \ + (head) = (link)->next; \ + if ((link)->next) \ + (link)->next->prev = (link)->prev; \ + BLOCK_END + // --- Dynamically allocated strings ------------------------------------------- // Basically a string builder to abstract away manual memory management. @@ -190,6 +218,49 @@ str_append_printf (struct str *self, const char *fmt, ...) // --- Utilities --------------------------------------------------------------- +static bool +set_blocking (int fd, bool blocking) +{ + int flags = fcntl (fd, F_GETFL); + bool prev = !(flags & O_NONBLOCK); + if (blocking) + flags &= ~O_NONBLOCK; + else + flags |= O_NONBLOCK; + return prev; +} + +static void +xclose (int fd) +{ + while (close (fd) == -1) + if (errno != EINTR) + break; +} + +static char *xstrdup_printf (const char *, ...) ATTRIBUTE_PRINTF (1, 2); + +static char * +xstrdup_printf (const char *format, ...) +{ + va_list ap; + struct str tmp; + str_init (&tmp); + va_start (ap, format); + str_append_vprintf (&tmp, format, ap); + va_end (ap); + return str_steal (&tmp); +} + +static char * +format_host_port_pair (const char *host, const char *port) +{ + // IPv6 addresses mess with the "colon notation"; let's go with RFC 2732 + if (strchr (host, ':')) + return xstrdup_printf ("[%s]:%s", host, port); + return xstrdup_printf ("%s:%s", host, port); +} + static bool xstrtoul (unsigned long *out, const char *s, int base) { -- cgit v1.2.3