Hello, On Wednesday 05 March 2008 10:18:10 Johannes Sixt wrote: > It's not the same on Windows, which returns: > case1: -1 > case2: 5 > case3: 5 > case4: 5 > > BTW, this is not only an issue of vsnprintf, but also of snprintf! 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@xxxxxxxxxxx> 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@xxxxxxxxxxx -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html