Hello, On Wednesday 05 March 2008 15:28:48 Johannes Sixt wrote: > > Please note that it actually copies data to str. > > ... in the case where the buffer is too small? This won't be a problem for > our users. Did some more tests. HPUX (v)snprintf() writes chars just well, but returns bogus. So no need to copy data explicitly here as well. I'm too quick on "Send" button and slow in testing; sorry. > > +# 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. > > We don't need two configuration variables. I think we can assume that if > vsnprintf is broken, then snprintf will be broken, too: I don't know. Right now I'm aware of 2 OSes that return bogus - HPUX and Windows. I the rest of bugus OSes is the same, 1 config is enough. Thank you for your comments; is this better? diff --git a/Makefile b/Makefile index ca5aad9..6af7132 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,10 @@ all:: # Define V=1 to have a more verbose compile. # +# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf() +# or 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 +633,10 @@ 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 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..8e1cd5f 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@ +SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@ diff --git a/configure.ac b/configure.ac index 85d7ef5..a3bbfa6 100644 --- a/configure.ac +++ b/configure.ac @@ -326,6 +326,38 @@ else NO_C99_FORMAT= fi AC_SUBST(NO_C99_FORMAT) +# +# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf() +# or 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 snprintf() and/or vsnprintf() return bogus], + [ac_cv_snprintf_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; + if (snprintf(buf, 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) ## Checks for library functions. diff --git a/git-compat-util.h b/git-compat-util.h index 2a40703..0aa04eb 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -209,6 +209,15 @@ 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, ...); +#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..9f30b22 --- /dev/null +++ b/compat/snprintf.c @@ -0,0 +1,39 @@ +#include "../git-compat-util.h" + +#undef vsnprintf +int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap) +{ + char *s; + + int ret = vsnprintf(str, maxsize, format, ap); + if (ret != -1 ) + return ret; + + s = NULL; + + while (ret == -1) { + maxsize *= 4; + str = realloc(s, maxsize); + if (! str) { + free(s); + return -1; + } + s = str; + ret = vsnprintf(str, maxsize, format, ap); + } + 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