diff options
author | William Hubbs <w.d.hubbs@gmail.com> | 2018-02-09 16:27:12 -0600 |
---|---|---|
committer | William Hubbs <w.d.hubbs@gmail.com> | 2018-02-09 16:27:12 -0600 |
commit | 4616f8f809ee8566904ca37f2b8bf0409a487475 (patch) | |
tree | 77fccbcaf254f3ad840ecfea2f1f4a5b43a33078 /src/includes | |
parent | 287d71bd2591ddec73efe356db081020e65cd922 (diff) |
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.
Diffstat (limited to 'src/includes')
-rw-r--r-- | src/includes/helpers.h | 49 |
1 files changed, 49 insertions, 0 deletions
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 <stdarg.h> #include <stdbool.h> #include <sys/stat.h> @@ -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 |