From 4616f8f809ee8566904ca37f2b8bf0409a487475 Mon Sep 17 00:00:00 2001 From: William Hubbs Date: Fri, 9 Feb 2018 16:27:12 -0600 Subject: helpers.h: add xasprintf function This is our own version of asprintf(). This original code was written by Mike Frysinger, and I was able to modify it to use our memory helper functions. We need a version of this code because it is not available on glibc at least without defining _GNU_SOURCE, and I would rather not do that. This is the first step in improving string handling in OpenRC for #207. --- src/includes/helpers.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'src') diff --git a/src/includes/helpers.h b/src/includes/helpers.h index 8d8b16e8..3657ee74 100644 --- a/src/includes/helpers.h +++ b/src/includes/helpers.h @@ -53,6 +53,7 @@ } while (/* CONSTCOND */ 0) #endif +#include #include #include @@ -123,4 +124,52 @@ _unused static bool existss(const char *pathname) return (stat(pathname, &buf) == 0 && buf.st_size != 0); } +/* + * This is an OpenRC specific version of the asprintf() function. + * We do this to avoid defining the _GNU_SOURCE feature test macro on + * glibc systems and to insure that we have a consistent function across + * platforms. This also allows us to call our xmalloc and xrealloc + * functions to handle memory allocation. + * this function was originally written by Mike Frysinger. + */ +_unused static int xasprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int len; + int memlen; + char *ret; + + /* + * Start with a buffer size that should cover the vast majority of uses + * (path construction). + */ + memlen = 4096; + ret = xmalloc(memlen); + + va_start(ap, fmt); + len = vsnprintf(ret, memlen, fmt, ap); + va_end(ap); + if (len >= memlen) { + /* + * Output was truncated, so increase buffer to exactly what we need. + */ + memlen = len + 1; + ret = xrealloc(ret, memlen); + va_start(ap, fmt); + len = vsnprintf(ret, len + 1, fmt, ap); + va_end(ap); + if (len >= memlen) { + /* Give up! */ + free(ret); + return -1; + } + } + if (len < 0) { + free(ret); + return -1; + } + *strp = ret; + return len; +} + #endif -- cgit v1.2.3