diff --git a/lib/dropin.c b/lib/dropin.c index a3c28b04..23d2b136 100644 --- a/lib/dropin.c +++ b/lib/dropin.c @@ -125,27 +125,36 @@ char *get_current_dir_name(void) #endif #ifndef HAVE_ASPRINTF -int asprintf(char **buf, const char *fmt, ...) +int asprintf(char **buf, const char *fmt, ...) { + int result; + va_list ap; + va_start(ap, fmt); + result = vasprintf(buf, fmt, ap); + va_end(ap); + return result; +} + +int vasprintf(char **buf, const char *fmt, va_list ap) { { int status; - va_list ap; + va_list aq; int len; len = 4096; *buf = xmalloc(len); - va_start(ap, fmt); - status = vsnprintf(*buf, len, fmt, ap); - va_end(ap); + va_copy(aq, ap); + status = vsnprintf(*buf, len, fmt, aq); + va_end(aq); if(status >= 0) *buf = xrealloc(*buf, status + 1); if(status > len - 1) { len = status; - va_start(ap, fmt); - status = vsnprintf(*buf, len, fmt, ap); - va_end(ap); + va_copy(aq, ap); + status = vsnprintf(*buf, len, fmt, aq); + va_end(aq); } return status; diff --git a/lib/dropin.h b/lib/dropin.h index eabc4c4d..72109c84 100644 --- a/lib/dropin.h +++ b/lib/dropin.h @@ -36,6 +36,7 @@ extern char *get_current_dir_name(void); #ifndef HAVE_ASPRINTF extern int asprintf(char **, const char *, ...); +extern int vasprintf(char **, const char *, va_list ap); #endif #ifndef HAVE_GETNAMEINFO diff --git a/lib/xalloc.h b/lib/xalloc.h index 7cb486a2..51f99bdf 100644 --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -24,3 +24,6 @@ void *xcalloc PARAMS ((size_t n, size_t s)); void *xrealloc PARAMS ((void *p, size_t n)) __attribute__ ((__malloc__)); char *xstrdup PARAMS ((const char *s)) __attribute__ ((__malloc__)); + +extern int xasprintf(char **strp, const char *fmt, ...); +extern int xvasprintf(char **strp, const char *fmt, va_list ap); diff --git a/lib/xmalloc.c b/lib/xmalloc.c index d02f41b9..51356e46 100644 --- a/lib/xmalloc.c +++ b/lib/xmalloc.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #if STDC_HEADERS # include @@ -138,3 +140,21 @@ xcalloc (n, s) } #endif /* NOT_USED */ + +int xasprintf(char **strp, const char *fmt, ...) { + int result; + va_list ap; + va_start(ap, fmt); + result = xvasprintf(strp, fmt, ap); + va_end(ap); + return result; +} + +int xvasprintf(char **strp, const char *fmt, va_list ap) { + int result = vasprintf(strp, fmt, ap); + if(result < 0) { + fprintf(stderr, "vasprintf() failed: %s\n", strerror(errno)); + exit(xalloc_exit_failure); + } + return result; +}