> 2011-09-22 Bruno Haible <br...@clisp.org> > > strerror_r-posix: Avoid a link error on MSVC. > * m4/strerror_r.m4 (gl_PREREQ_STRERROR_R): Check for snprintf. > * lib/strerror_r.c (snprintf): Define to _snprintf if it doesn't exist.
Oops, that fixed the link error, but at the cost of a test suite failure: test-strerror_r.c:119: assertion failed FAIL: test-strerror_r.exe The Microsoft _snprintf() function not only has a different return value convention than ISO C snprintf(), it also does not NUL-terminate the result! Workaround: 2011-09-25 Bruno Haible <br...@clisp.org> strerror_r-posix: Fix for MSVC 9. * lib/strerror_r.c (local_snprintf): New function. (snprintf): Define to local_snprintf, not to _snprintf. --- lib/strerror_r.c.orig Sun Sep 25 14:50:08 2011 +++ lib/strerror_r.c Sun Sep 25 14:49:15 2011 @@ -87,9 +87,24 @@ #endif /* On MSVC, there is no snprintf() function, just a _snprintf(). - It is of lower quality, but sufficient for the simple use here. */ + It is of lower quality, but sufficient for the simple use here. + We only have to make sure to NUL terminate the result (_snprintf + does not NUL terminate, like strncpy). */ #if !HAVE_SNPRINTF -# define snprintf _snprintf +static int +local_snprintf (char *buf, size_t buflen, const char *format, ...) +{ + va_list args; + int result; + + va_start (args, format); + result = _vsnprintf (buf, buflen, format, args); + va_end (args); + if (buflen > 0 && (result < 0 || result >= buflen)) + buf[buflen - 1] = '\0'; + return result; +} +# define snprintf local_snprintf #endif /* Copy as much of MSG into BUF as possible, without corrupting errno. -- In memoriam Safia Ahmed-jan <http://en.wikipedia.org/wiki/Safia_Ahmed-jan>