]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
stdio-windows: Add fallback code for very old mingw without vasprintf.
authorBruno Haible <bruno@clisp.org>
Thu, 6 Nov 2025 19:16:45 +0000 (20:16 +0100)
committerBruno Haible <bruno@clisp.org>
Thu, 6 Nov 2025 19:16:45 +0000 (20:16 +0100)
Reported by Eli Zaretskii <eliz@gnu.org> in
<https://lists.gnu.org/archive/html/emacs-devel/2025-11/msg00194.html>.

* lib/stdio-consolesafe.c (vasprintf) [!HAVE_VASPRINTF]: New function.
* modules/stdio-windows (configure.ac): Test whether vasprintf exists.

ChangeLog
lib/stdio-consolesafe.c
modules/stdio-windows

index ab93d8334906ea5fc673024552101ec992619d4f..551a7acae00ebd0c0255894d6994fdcd8c80c9bf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-11-06  Bruno Haible  <bruno@clisp.org>
+
+       stdio-windows: Add fallback code for very old mingw without vasprintf.
+       Reported by Eli Zaretskii <eliz@gnu.org> in
+       <https://lists.gnu.org/archive/html/emacs-devel/2025-11/msg00194.html>.
+       * lib/stdio-consolesafe.c (vasprintf) [!HAVE_VASPRINTF]: New function.
+       * modules/stdio-windows (configure.ac): Test whether vasprintf exists.
+
 2025-11-06  Bruno Haible  <bruno@clisp.org>
 
        stdio-windows: New module.
index fbea20be2242d7c63286279570b7907bdbd80d85..b5ca8cc0125d2ff7e0fd0c123293f4955dda51a2 100644 (file)
@@ -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 <errno.h>
+#  include <stdarg.h>
+
+/* 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.  */
index d9489e3e7c7c529969d2af63ced2d37aa5993944..8cbca1be1b0161c10423b824902a5833318288fe 100644 (file)
@@ -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