2011/6/30 Eric Blake <eblake(a)redhat.com>:
On 06/30/2011 12:00 PM, Eric Blake wrote:
> Gnulib documents that mingw [v]snprintf is broken (it returns -1
> on out-of-space, instead of the count of what would have been
> printed); but while we were using the snprintf wrapper, we had
> not yet been using the vsnprintf wrapper.
>
> * bootstrap.conf (gnulib_modules): Add vsnprintf.
> Reported by Matthias Bolte.
> ---
> bootstrap.conf | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
Followup. There are two forks of mingw - the older mingw project is
32-bit only, and has added wrappers into their w32api libraries that
substitute the broken [v]snprintf of msvcrt with a mingw-specific one
that is POSIX-compliant out of the box. Then there is the mingw64
project, which can compile for both 32-bit and 64-bit, and where their
w32api libraries do not yet override [v]snprintf. [For reference,
Fedora 15 uses the older mingw project, but Fedora 16 is hoping to
switch to the newer mingw64 project; meanwhile, cygwin ships with
cross-compilers for both flavors, which is how I tested the vsnprintf
behavior of both flavors]
The gnulib documentation tends to lag various mingw fixes, and (to date)
has not been making any distinction between the mingw and mingw64 projects.
This patch will help mingw64, so it is worth applying. However,
Matthias and I spent some time on IRC and we are quite confused at why
his mingw build is having issues - since mingw uses wrappers that work
and do not need the gnulib replacement in the first place, at least at
configure time, this change to bootstrap.conf did not change anything
for his build. I'm wondering if maybe libtools attempts to directly
invoke ld instead of going through gcc as the linker are causing
problems, where the configure test used gcc and sees the working wrapper
vsnprintf, but then virsh is compiled via libtool and ends up using the
native broken vsnprintf. At least, that's all I was able to guess :(
Simple tests show that [v]snprintf works correctly with mingw (I
didn't test mingw64) in case of a too small buffer. It's only broken
in the context of libvirt. I finally figured out that libintl is the
cause for this, as Eric already suggested as a possible cause on IRC.
It's not related to libtool at all.
libintl.h is included by gnulib's gettext.h, that is included by
internal.h, that is included by buf.h, that is included by buf.c. This
it how we get it there to break in libvirt, because libintl.h (from
http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtim...)
contains this section
#if 1
#if !(defined snprintf && defined _GL_STDIO_H) /* don't override gnulib */
#undef snprintf
#define snprintf libintl_snprintf
extern int snprintf (char *, size_t, const char *, ...);
#endif
#if !(defined vsnprintf && defined _GL_STDIO_H) /* don't override gnulib */
#undef vsnprintf
#define vsnprintf libintl_vsnprintf
extern int vsnprintf (char *, size_t, const char *, va_list);
#endif
#endif
gnulib's stdio.h is included prior to the inclusion of libintl.h so
_GL_STDIO_H is defined, but gnulib detected that it doesn't need to
replace [v]snprintf, therefore [v]snprintf isn't defined and both
#if's are true and libintl.h replaces [v]snprintf with it's own broken
version. I can reproduce the problem in a test program by including
said libintl.h.
--
Matthias Bolte
http://photron.blogspot.com