changeset 859:c4754c5770f3 HEAD

We weren't using va_list properly, especially gcc/PowerPC didn't like it.
author Timo Sirainen <tss@iki.fi>
date Fri, 27 Dec 2002 18:02:25 +0200
parents 8f4bd02461e0
children c3d0eddd6065
files configure.in src/lib/failures.c src/lib/macros.h src/lib/str.c src/lib/strfuncs.c
diffstat 5 files changed, 107 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/configure.in	Fri Dec 27 17:39:10 2002 +0200
+++ b/configure.in	Fri Dec 27 18:02:25 2002 +0200
@@ -1,7 +1,7 @@
 AC_INIT(src)
 
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(dovecot, 0.99.4)
+AM_INIT_AUTOMAKE(dovecot, 0.99.5rc1)
 
 AM_MAINTAINER_MODE
 
@@ -515,6 +515,84 @@
   AC_MSG_RESULT(no)
 ])
 
+dnl ***
+dnl *** va_copy checks (from GLIB)
+dnl ***
+
+AC_CACHE_CHECK([for an implementation of va_copy()],lib_cv_va_copy,[
+	AC_TRY_RUN([
+	#include <stdarg.h>
+	void f (int i, ...) {
+	va_list args1, args2;
+	va_start (args1, i);
+	va_copy (args2, args1);
+	if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+	  exit (1);
+	va_end (args1); va_end (args2);
+	}
+	int main() {
+	  f (0, 42);
+	  return 0;
+	}],
+	[lib_cv_va_copy=yes],
+	[lib_cv_va_copy=no],
+	[])
+])
+AC_CACHE_CHECK([for an implementation of __va_copy()],lib_cv___va_copy,[
+	AC_TRY_RUN([
+	#include <stdarg.h>
+	void f (int i, ...) {
+	va_list args1, args2;
+	va_start (args1, i);
+	__va_copy (args2, args1);
+	if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+	  exit (1);
+	va_end (args1); va_end (args2);
+	}
+	int main() {
+	  f (0, 42);
+	  return 0;
+	}],
+	[lib_cv___va_copy=yes],
+	[lib_cv___va_copy=no],
+	[])
+])
+
+if test "x$lib_cv_va_copy" = "xyes"; then
+  va_copy_func=va_copy
+else if test "x$lib_cv___va_copy" = "xyes"; then
+  va_copy_func=__va_copy
+fi
+fi
+
+if test -n "$va_copy_func"; then
+  AC_DEFINE_UNQUOTED(VA_COPY,$va_copy_func,[A 'va_copy' style function])
+fi
+
+AC_CACHE_CHECK([whether va_lists can be copied by value],lib_cv_va_val_copy,[
+	AC_TRY_RUN([
+	#include <stdarg.h>
+	void f (int i, ...) {
+	va_list args1, args2;
+	va_start (args1, i);
+	args2 = args1;
+	if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+	  exit (1);
+	va_end (args1); va_end (args2);
+	}
+	int main() {
+	  f (0, 42);
+	  return 0;
+	}],
+	[lib_cv_va_val_copy=yes],
+	[lib_cv_va_val_copy=no],
+	[])
+])
+
+if test "x$lib_cv_va_val_copy" = "xno"; then
+  AC_DEFINE(VA_COPY_AS_ARRAY,1, ['va_lists' cannot be copies as values])
+fi
+
 dnl **
 dnl ** SSL
 dnl **
--- a/src/lib/failures.c	Fri Dec 27 17:39:10 2002 +0200
+++ b/src/lib/failures.c	Fri Dec 27 18:02:25 2002 +0200
@@ -83,6 +83,7 @@
 			    const char *format, va_list args)
 {
 	static int recursed = 0;
+	va_list args2;
 	int old_errno = errno;
 
 	if (recursed == 2) {
@@ -100,6 +101,8 @@
 			log_fd = stderr;
 	}
 
+	VA_COPY(args2, args);
+
 	t_push();
 	if (recursed == 2) {
 		/* write without fixing format, that probably killed us
@@ -107,7 +110,7 @@
 
 		/* make sure there's no %n in there */
                 (void)printf_string_upper_bound(format, args);
-		vfprintf(f, format, args);
+		vfprintf(f, format, args2);
 		fputs(" - recursed!", f);
 	} else {
 		write_prefix(f);
@@ -116,7 +119,7 @@
 		format = printf_string_fix_format(format);
 		/* make sure there's no %n in there */
                 (void)printf_string_upper_bound(format, args);
-		vfprintf(f, format, args);
+		vfprintf(f, format, args2);
 	}
 
 	fputc('\n', f);
@@ -270,6 +273,8 @@
 
 static void syslog_handler(int level, const char *format, va_list args)
 {
+	va_list args2;
+
 	static int recursed = 0;
 
 	if (recursed != 0)
@@ -278,9 +283,10 @@
 	recursed++;
 
 	/* make sure there's no %n in there */
+	VA_COPY(args2, args);
 	(void)printf_string_upper_bound(format, args);
 
-	vsyslog(level, format, args);
+	vsyslog(level, format, args2);
 	recursed--;
 }
 
--- a/src/lib/macros.h	Fri Dec 27 17:39:10 2002 +0200
+++ b/src/lib/macros.h	Fri Dec 27 18:02:25 2002 +0200
@@ -40,7 +40,8 @@
 #define POINTER_CAST_TO(p, type) \
 	((type) ((const char *) (p) - (const char *) NULL))
 
-/* Define VA_COPY() to do the right thing for copying va_list variables. */
+/* Define VA_COPY() to do the right thing for copying va_list variables.
+   config.h may have already defined VA_COPY as va_copy or __va_copy. */
 #ifndef VA_COPY
 #  if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
 #    define VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
--- a/src/lib/str.c	Fri Dec 27 17:39:10 2002 +0200
+++ b/src/lib/str.c	Fri Dec 27 18:02:25 2002 +0200
@@ -123,8 +123,11 @@
 {
 	char *buf;
 	int ret;
+	va_list args2;
 	size_t len, append_len;
 
+	VA_COPY(args2, args);
+
 	len = buffer_get_used_size(str);
 
 	fmt = printf_string_fix_format(fmt);
@@ -133,10 +136,10 @@
 	buf = buffer_append_space(str, append_len);
 
 #ifdef HAVE_VSNPRINTF
-	ret = vsnprintf(buf, append_len, fmt, args);
+	ret = vsnprintf(buf, append_len, fmt, args2);
 	i_assert(ret >= 0 && (size_t)ret <= append_len);
 #else
-	ret = vsprintf(buf, fmt, args);
+	ret = vsprintf(buf, fmt, args2);
 	i_assert(ret >= 0);
 #endif
 
--- a/src/lib/strfuncs.c	Fri Dec 27 17:39:10 2002 +0200
+++ b/src/lib/strfuncs.c	Fri Dec 27 18:02:25 2002 +0200
@@ -97,7 +97,7 @@
 #ifndef HAVE_VSNPRINTF
 	char *buf;
 #endif
-	va_list args;
+	va_list args, args2;
 	ssize_t len;
 	int ret;
 
@@ -106,18 +106,21 @@
 	t_push();
 
 	va_start(args, format);
+	VA_COPY(args2, args);
+
 	format = printf_string_fix_format(format);
 	len = printf_string_upper_bound(format, args);
-	va_end(args);
 
 	i_assert(len >= 0);
 
 #ifdef HAVE_VSNPRINTF
-	len = vsnprintf(dest, max_chars, format, args);
+	len = vsnprintf(dest, max_chars, format, args2);
 #else
 	buf = t_buffer_get(len);
-	len = vsprintf(buf, format, args);
+	len = vsprintf(buf, format, args2);
 #endif
+	va_end(args);
+
 	if (len < 0) {
 		/* some error occured */
 		len = 0;
@@ -213,6 +216,7 @@
 char *p_strdup_vprintf(Pool pool, const char *format, va_list args)
 {
 	char *ret;
+	va_list args2;
 	size_t len;
 
 	i_assert(format != NULL);
@@ -220,15 +224,17 @@
 	if (pool != data_stack_pool)
 		t_push();
 
+	VA_COPY(args2, args);
+
 	format = printf_string_fix_format(format);
 
 	len = printf_string_upper_bound(format, args);
         ret = p_malloc(pool, len);
 
 #ifdef HAVE_VSNPRINTF
-	vsnprintf(ret, len, format, args);
+	vsnprintf(ret, len, format, args2);
 #else
-	vsprintf(ret, format, args);
+	vsprintf(ret, format, args2);
 #endif
 	if (pool != data_stack_pool)
 		t_pop();