From: Timo Sirainen Date: Thu, 12 Jun 2008 21:28:18 +0000 (+0300) Subject: Support systems with non-C99 vsnprintf(). X-Git-Tag: 1.2.alpha1~311 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=87391ba3b72b9b78dd67f09b329e9463556c03ed;p=thirdparty%2Fdovecot%2Fcore.git Support systems with non-C99 vsnprintf(). --HG-- branch : HEAD --- diff --git a/configure.in b/configure.in index 8fb53571d3..6c6d8ea11e 100644 --- a/configure.in +++ b/configure.in @@ -1373,11 +1373,10 @@ AC_CACHE_CHECK([for C99 vsnprintf()],i_cv_c99_vsnprintf,[ return f("hello %s%d", "world", 1); }]])], [i_cv_c99_vsnprintf=yes], - [i_cv_c99_vsnprintf=no], - []) + [i_cv_c99_vsnprintf=no]) ]) if test $i_cv_c99_vsnprintf = no; then - AC_ERROR([You don't appear to have C99 compatible vsnprintf() call]) + AC_DEFINE(HAVE_OLD_VSNPRINTF,, Define if you don't have C99 compatible vsnprintf() call) fi dnl *** diff --git a/src/lib/compat.c b/src/lib/compat.c index 57e24b6524..192d300481 100644 --- a/src/lib/compat.c +++ b/src/lib/compat.c @@ -238,3 +238,41 @@ unsigned long long int my_strtoll(const char *nptr, char **endptr, int base) #endif } #endif + +#ifdef HAVE_OLD_VSNPRINTF +#undef vsnprintf +int my_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + size_t tmp_size; + char *tmp; + int ret; + + /* On overflow HP-UX returns -1, IRIX and Tru64 return size-1. */ + ret = vsnprintf(str, size, format, ap); + if (ret >= 0 && (size_t)ret+1 != size) + return ret; + + /* see if data stack has enough available space for it */ + tmp_size = t_get_bytes_available(); + if (tmp_size > size) { + tmp = t_buffer_get(tmp_size); + ret = vsnprintf(tmp, tmp_size, format, ap); + if (ret >= 0 && (size_t)ret+1 != size) + return ret; + } else { + tmp_size = size; + } + + /* try to allocate enough memory to get it to fit. */ + do { + tmp_size = nearest_power(tmp_size+1); + tmp = i_malloc(tmp_size); + ret = vsnprintf(tmp, tmp_size, format, ap); + i_free(tmp); + if (ret >= 0 && (size_t)ret+1 != size) + return ret; + } while (tmp_size < 1024*1024); + + i_panic("my_vsnprintf(): Output string too big"); +} +#endif diff --git a/src/lib/compat.h b/src/lib/compat.h index 960d1a18a7..9c96491532 100644 --- a/src/lib/compat.h +++ b/src/lib/compat.h @@ -193,6 +193,12 @@ unsigned long long int my_strtoull(const char *nptr, char **endptr, int base); unsigned long long int my_strtoll(const char *nptr, char **endptr, int base); #endif +#ifdef HAVE_OLD_VSNPRINTF +# include +# define vsnprintf my_vsnprintf +int my_vsnprintf(char *str, size_t size, const char *format, va_list ap); +#endif + /* ctype.h isn't safe with signed chars, use our own instead if really needed */ #define i_toupper(x) ((char) toupper((int) (unsigned char) (x)))