From 9dc404958e9c91f33f75450f69b690a5e676af04 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 24 May 2016 20:50:35 +0300 Subject: [PATCH] util: Add xasprintf portable asprintf variant Include a portable asprintf variant that works on any C99 conforming platform. Signed-off-by: Pantelis Antoniou Signed-off-by: David Gibson --- util.c | 30 ++++++++++++++++++++++++++++++ util.h | 1 + 2 files changed, 31 insertions(+) diff --git a/util.c b/util.c index fb124ee..3550f86 100644 --- a/util.c +++ b/util.c @@ -46,6 +46,36 @@ char *xstrdup(const char *s) return d; } +/* based in part from (3) vsnprintf */ +int xasprintf(char **strp, const char *fmt, ...) +{ + int n, size = 128; /* start with 128 bytes */ + char *p; + va_list ap; + + /* initial pointer is NULL making the fist realloc to be malloc */ + p = NULL; + while (1) { + p = xrealloc(p, size); + + /* Try to print in the allocated space. */ + va_start(ap, fmt); + n = vsnprintf(p, size, fmt, ap); + va_end(ap); + + /* If that worked, return the string. */ + if (n > -1 && n < size) + break; + /* Else try again with more space. */ + if (n > -1) /* glibc 2.1 */ + size = n + 1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + } + *strp = p; + return strlen(p); +} + char *join_path(const char *path, const char *name) { int lenp = strlen(path); diff --git a/util.h b/util.h index f800b60..f5c4f1b 100644 --- a/util.h +++ b/util.h @@ -59,6 +59,7 @@ static inline void *xrealloc(void *p, size_t len) } extern char *xstrdup(const char *s); +extern int xasprintf(char **strp, const char *fmt, ...); extern char *join_path(const char *path, const char *name); /**