Re: [PATCH] Add compat/vsnprintf.c for systems that returns -1 on maxsize reached

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Michal Rokos
Date: Wednesday, March 5, 2008 - 6:55 am

Hello,

On Wednesday 05 March 2008 10:18:10 Johannes Sixt wrote:

Hmm, HPUX has the same issue for snprint() as is for vsnprintf().

Do you think that following patch suffices your needs. Please note that it 
actually copies data to str.

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

diff --git a/Makefile b/Makefile
index ca5aad9..49d5ab6 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,14 @@ all::
 
 # Define V=1 to have a more verbose compile.
 #
+# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
+# returns -1 instead of number of characters which would have been written
+# to the final string if enough space had been available.
+#
+# Define VSNPRINTF_RETURNS_BOGUS if your are on a system which vsnprintf()
+# returns -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.
 #
@@ -629,6 +637,14 @@ endif
 ifdef NO_C99_FORMAT
 	BASIC_CFLAGS += -DNO_C99_FORMAT
 endif
+ifdef SNPRINTF_RETURNS_BOGUS
+	COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS
+	COMPAT_OBJS += compat/snprintf.o
+endif
+ifdef VSNPRINTF_RETURNS_BOGUS
+	COMPAT_CFLAGS += -DVSNPRINTF_RETURNS_BOGUS
+	COMPAT_OBJS += compat/snprintf.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..a10a4af 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -46,3 +46,5 @@ NO_MKDTEMP=@NO_MKDTEMP@
 NO_ICONV=@NO_ICONV@
 OLD_ICONV=@OLD_ICONV@
 NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
+SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@
+VSNPRINTF_RETURNS_BOGUS=@VSNPRINTF_RETURNS_BOGUS@
diff --git a/configure.ac b/configure.ac
index 85d7ef5..b902888 100644
--- a/configure.ac
+++ b/configure.ac
@@ -326,6 +326,57 @@ else
 	NO_C99_FORMAT=
 fi
 AC_SUBST(NO_C99_FORMAT)
+#
+# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
+# returns -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 snprintf() returns bogus],
+ [ac_cv_snprintf_returns_bogus],
+[
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
+		[[char buf[1];
+		  if (snprintf(bug, 1, "%s", "12345") != 5) return 1]])],
+	[ac_cv_snprintf_returns_bogus=no],
+	[ac_cv_snprintf_returns_bogus=yes])
+])
+if test $ac_cv_snprintf_returns_bogus = yes; then
+	SNPRINTF_RETURNS_BOGUS=UnfortunatelyYes
+else
+	SNPRINTF_RETURNS_BOGUS=
+fi
+AC_SUBST(SNPRINTF_RETURNS_BOGUS)
+#
+# Define VSNPRINTF_RETURNS_BOGUS if your are on a system which vsnprintf()
+# returns -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() returns bogus],
+ [ac_cv_vsnprintf_returns_bogus],
+[
+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_vsnprintf_returns_bogus=no],
+	[ac_cv_vsnprintf_returns_bogus=yes])
+])
+if test $ac_cv_vsnprintf_returns_bogus = yes; then
+	VSNPRINTF_RETURNS_BOGUS=UnfortunatelyYes
+else
+	VSNPRINTF_RETURNS_BOGUS=
+fi
+AC_SUBST(VSNPRINTF_RETURNS_BOGUS)
 
 
 ## Checks for library functions.
diff --git a/git-compat-util.h b/git-compat-util.h
index 2a40703..6618c08 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -209,6 +209,18 @@ void *gitmemmem(const void *haystack, size_t haystacklen,
 extern FILE *git_fopen(const char*, const char*);
 #endif
 
+#ifdef SNPRINTF_RETURNS_BOGUS
+#define snprintf git_snprintf
+extern int git_snprintf(char *str, size_t maxsize,
+                        const char *format, ...);
+#endif
+
+#ifdef VSNPRINTF_RETURNS_BOGUS
+#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/snprintf.c
new file mode 100644
index 0000000..bc0d37c
--- /dev/null
+++ b/compat/snprintf.c
@@ -0,0 +1,37 @@
+#include "../git-compat-util.h"
+
+#undef vsnprintf
+int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
+{
+   char *s;
+   int size;
+
+   int ret = vsnprintf(str, maxsize, format, ap);
+   if (ret != -1 ) return ret;
+
+   s = NULL;
+   size = maxsize;
+   while ( ret == -1 )
+   {
+      size *= 4;
+      s = realloc(s, size);
+      if (! s) return -1;
+      ret = vsnprintf(s, size, format, ap);
+   }
+   if (str && maxsize > 0) memcpy(str, s, maxsize);
+   free(s);
+   return ret;
+}
+
+int git_snprintf(char *str, size_t maxsize, const char *format, ...)
+{
+   va_list ap;
+   int ret;
+
+   va_start(ap, format);
+   ret = git_vsnprintf(str, maxsize, format, ap);
+   va_end(ap);
+
+   return ret;
+}
+



-- 
Michal Rokos

NextSoft s.r.o.
Vyskočilova 1/1410
140 21 Praha 4
phone:  +420 267 224 311
fax:    +420 267 224 307
mobile: +420 736 646 591
e-mail: michal.rokos@nextsoft.cz
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [PATCH] Add compat/vsnprintf.c for systems that return ..., Johannes Schindelin, (Tue Mar 4, 7:09 am)
Re: [PATCH] Add compat/vsnprintf.c for systems that return ..., Finn Arne Gangstad, (Tue Mar 4, 7:09 am)
Re: [PATCH] Add compat/vsnprintf.c for systems that return ..., Michal Rokos, (Wed Mar 5, 6:55 am)