git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add compat/vsnprintf.c for systems that returns -1 on maxsize reached
@ 2008-03-04 13:59 Michal Rokos
  2008-03-04 14:09 ` Johannes Schindelin
                   ` (3 more replies)
  0 siblings, 4 replies; 26+ messages in thread
From: Michal Rokos @ 2008-03-04 13:59 UTC (permalink / raw)
  To: GIT

This PATCH is NOT intended to be merged (yet).

Some systems (namely HPUX) return -1 when maxsize in vsnprintf() is reached. 
So replace that broken vsnprintf() with our own that returns correct value 
upon overflow.

Could anybody give it some testing since I don't know how many broken systems 
are out there?

If anybody could think of some better define than BROKEN_VSNPRINTF, I'm all 
ears.

Linux is OK, HPUX is detected to be broken. On HPUX (11.23) test suite with 
defined BROKEN_VSNPRINTF fails in 8 *.sh testsuites, without it it fails in 
140 *.sh testsuites (out of 241).

Signed-off-by: Michal Rokos <michal.rokos@nextsoft.cz>

diff --git a/Makefile b/Makefile
index ca5aad9..a1dbf1d 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,10 @@ all::
 
 # Define V=1 to have a more verbose compile.
 #
+# Define BROKEN_VSNPRINTF if your are on a system which vsnprintf() return
+# something else (typically -1) instead of number of characters which would
+# have been written to the final string if enough space had been available.
+#
 # Define FREAD_READS_DIRECTORIES if your are on a system which succeeds
 # when attempting to read from an fopen'ed directory.
 #
@@ -526,6 +530,7 @@ ifeq ($(uname_S),HP-UX)
 	NO_UNSETENV = YesPlease
 	NO_HSTRERROR = YesPlease
 	NO_SYS_SELECT_H = YesPlease
+	BROKEN_VSNPRINTF = UnfortunatelyYes
 endif
 ifneq (,$(findstring arm,$(uname_M)))
 	ARM_SHA1 = YesPlease
@@ -629,6 +634,10 @@ endif
 ifdef NO_C99_FORMAT
 	BASIC_CFLAGS += -DNO_C99_FORMAT
 endif
+ifdef BROKEN_VSNPRINTF
+	COMPAT_CFLAGS += -DBROKEN_VSNPRINTF
+	COMPAT_OBJS += compat/vsnprintf.o
+endif
 ifdef FREAD_READS_DIRECTORIES
 	COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
 	COMPAT_OBJS += compat/fopen.o
diff --git a/config.mak.in b/config.mak.in
index ee6c33d..aaa98c6 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -46,3 +46,4 @@ NO_MKDTEMP=@NO_MKDTEMP@
 NO_ICONV=@NO_ICONV@
 OLD_ICONV=@OLD_ICONV@
 NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
+BROKEN_VSNPRINTF=@BROKEN_VSNPRINTF@
diff --git a/configure.ac b/configure.ac
index 85d7ef5..d4bb2b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -326,6 +326,37 @@ else
 	NO_C99_FORMAT=
 fi
 AC_SUBST(NO_C99_FORMAT)
+#
+# Define BROKEN_VSNPRINTF if your are on a system which vsnprintf() return
+# something else (typically -1) instead of number of characters which would
+# have been written to the final string if enough space had been available.
+AC_CACHE_CHECK([whether vsnprintf() is broken],
+ [ac_cv_broken_vsnprintf],
+[
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
+		#include "stdarg.h"
+
+		int test_vsnprintf(char *str, size_t maxsize, const char *format, ...)
+		{
+		  int ret;
+		  va_list ap;
+		  va_start(ap, format);
+		  ret = vsnprintf(str, maxsize, format, ap);
+		  va_end(ap);
+                  return ret;
+		}],
+		[[char buf[1];
+		  if (test_vsnprintf(buf, 1, "%s", "12345") != 5) return 1]])],
+	[ac_cv_broken_vsnprintf=no],
+	[ac_cv_broken_vsnprintf=yes])
+])
+if test $ac_cv_broken_vsnprintf = yes; then
+	BROKEN_VSNPRINTF=UnfortunatelyYes
+else
+	BROKEN_VSNPRINTF=
+fi
+AC_SUBST(BROKEN_VSNPRINTF)
 
 
 ## Checks for library functions.
diff --git a/git-compat-util.h b/git-compat-util.h
index 2a40703..5c392f8 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -209,6 +209,12 @@ void *gitmemmem(const void *haystack, size_t haystacklen,
 extern FILE *git_fopen(const char*, const char*);
 #endif
 
+#ifdef BROKEN_VSNPRINTF
+#define vsnprintf git_vsnprintf
+extern int git_vsnprintf(char *str, size_t maxsize,
+                         const char *format, va_list ap);
+#endif
+
 #ifdef __GLIBC_PREREQ
 #if __GLIBC_PREREQ(2, 1)
 #define HAVE_STRCHRNUL
diff --git a/dev/null b/compat/vsnprintf.c
new file mode 100644
index 0000000..263e00e
--- /dev/null
+++ b/compat/vsnprintf.c
@@ -0,0 +1,20 @@
+#include "../git-compat-util.h"
+
+#undef vsnprintf
+int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap);
+{
+	int ret = vsnprintf(s, maxsize, format, ap);
+	if (ret != -1 ) return ret;
+
+	s = NULL;
+	while ( ret == -1 )
+	{
+		maxsize = (maxsize*3)/2;
+		s = realloc(s, maxsize);
+		if (! s) return -1;
+		ret = vsnprintf(s, maxsize, format, ap);
+	}
+	free(s);
+	return ret;
+}
+

^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2008-03-10 10:05 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-04 13:59 [PATCH] Add compat/vsnprintf.c for systems that returns -1 on maxsize reached Michal Rokos
2008-03-04 14:09 ` Johannes Schindelin
2008-03-04 14:09 ` Finn Arne Gangstad
2008-03-04 16:19   ` Johannes Sixt
2008-03-04 14:12 ` Morten Welinder
2008-03-04 16:28 ` Johannes Sixt
2008-03-04 23:51   ` Wayne Davison
2008-03-05  8:37   ` Michal Rokos
2008-03-05  8:44     ` Jeff King
2008-03-05  9:18     ` Johannes Sixt
2008-03-05 13:55       ` Michal Rokos
2008-03-05 14:28         ` Johannes Sixt
2008-03-05 15:00           ` Michal Rokos
2008-03-05 15:22             ` Johannes Sixt
2008-03-05 15:48               ` Michal Rokos
2008-03-05 15:54             ` Wayne Davison
2008-03-05 16:04               ` Johannes Sixt
2008-03-05 22:33                 ` Wayne Davison
2008-03-05 21:05               ` Junio C Hamano
2008-03-05  9:22     ` Mike Ralphson
2008-03-05 10:35     ` Robert Haines
2008-03-05 13:58       ` Michal Rokos
2008-03-10  8:59   ` Michal Rokos
2008-03-10  9:28     ` Johannes Sixt
2008-03-10  9:47       ` Michal Rokos
2008-03-10 10:05         ` Johannes Sixt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).