]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Support systems with non-C99 vsnprintf().
authorTimo Sirainen <tss@iki.fi>
Thu, 12 Jun 2008 21:28:18 +0000 (00:28 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 12 Jun 2008 21:28:18 +0000 (00:28 +0300)
--HG--
branch : HEAD

configure.in
src/lib/compat.c
src/lib/compat.h

index 8fb53571d333a5479fd4fd3278e9b28125c65ec4..6c6d8ea11ef7f2a0bc36041735c964168449b0e2 100644 (file)
@@ -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 ***
index 57e24b65247effd5195c99295ef41cfe60ad192f..192d300481f51eb87b75898750b5afc5ffca77f5 100644 (file)
@@ -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
index 960d1a18a7c9c59725d0cb26ee8f98b4d045da77..9c96491532177ede1a1f98440fb90bafee9fbdb1 100644 (file)
@@ -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 <stdio.h>
+#  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)))