From: Bruno Haible Date: Thu, 6 Nov 2025 19:16:45 +0000 (+0100) Subject: stdio-windows: Add fallback code for very old mingw without vasprintf. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=19de62ef025bc39cf759ebd20c6b4733c7e27f27;p=thirdparty%2Fgnulib.git stdio-windows: Add fallback code for very old mingw without vasprintf. Reported by Eli Zaretskii in . * lib/stdio-consolesafe.c (vasprintf) [!HAVE_VASPRINTF]: New function. * modules/stdio-windows (configure.ac): Test whether vasprintf exists. --- diff --git a/ChangeLog b/ChangeLog index ab93d83349..551a7acae0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2025-11-06 Bruno Haible + + stdio-windows: Add fallback code for very old mingw without vasprintf. + Reported by Eli Zaretskii in + . + * lib/stdio-consolesafe.c (vasprintf) [!HAVE_VASPRINTF]: New function. + * modules/stdio-windows (configure.ac): Test whether vasprintf exists. + 2025-11-06 Bruno Haible stdio-windows: New module. diff --git a/lib/stdio-consolesafe.c b/lib/stdio-consolesafe.c index fbea20be22..b5ca8cc012 100644 --- a/lib/stdio-consolesafe.c +++ b/lib/stdio-consolesafe.c @@ -75,6 +75,56 @@ gl_consolesafe_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *fp) # include "fseterr.h" +# if !HAVE_VASPRINTF + +# include +# include + +/* The old mingw (before mingw-w64) does not have the vasprintf function. + Define a suitable replacement here, that supports the same format + specifiers as the mingw *printf functions. */ + +static int +vasprintf (char **resultp, const char *format, va_list args) +{ + /* First try: Use a stack-allocated buffer. */ + char buf[2048]; + size_t bufsize = sizeof (buf); + int ret = __mingw_vsnprintf (buf, bufsize, format, args); + if (ret < 0) + return -1; + size_t nbytes = ret; + char *mem = (char *) malloc (nbytes + 1); + if (mem == NULL) + { + errno = ENOMEM; + return -1; + } + if (ret < bufsize) + { + /* The buffer was sufficiently large. */ + memcpy (mem, buf, nbytes + 1); + } + else + { + /* Second try: Use the heap-allocated memory. */ + ret = __mingw_vsnprintf (mem, nbytes + 1, format, args); + if (ret < 0) + { + int saved_errno = errno; + free (mem); + errno = saved_errno; + return -1; + } + if (ret != nbytes) + abort (); + } + *resultp = mem; + return nbytes; +} + +# endif + /* Bypass the functions __mingw_[v][f]printf, that trigger a bug in msvcrt, but without losing the support for modern format specifiers added by __mingw_*printf. */ diff --git a/modules/stdio-windows b/modules/stdio-windows index d9489e3e7c..8cbca1be1b 100644 --- a/modules/stdio-windows +++ b/modules/stdio-windows @@ -23,6 +23,7 @@ case "$host_os" in ;; esac gl_CONDITIONAL([GL_COND_OBJ_STDIO_CONSOLESAFE], [test $USES_MSVCRT = 1]) +AC_CHECK_FUNCS([vasprintf]) Makefile.am: if GL_COND_OBJ_STDIO_CONSOLESAFE