diff options
Diffstat (limited to 'tests/stdio-consolesafe.c')
| -rw-r--r-- | tests/stdio-consolesafe.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/tests/stdio-consolesafe.c b/tests/stdio-consolesafe.c index fbea20be..f634de13 100644 --- a/tests/stdio-consolesafe.c +++ b/tests/stdio-consolesafe.c @@ -1,5 +1,5 @@ /* msvcrt workarounds. - Copyright (C) 2025 Free Software Foundation, Inc. + Copyright (C) 2025-2026 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -74,6 +74,59 @@ gl_consolesafe_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *fp) #if defined __MINGW32__ && __USE_MINGW_ANSI_STDIO # include "fseterr.h" +# include <stdarg.h> + +# if !HAVE_VASPRINTF + +# include <errno.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 +local_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; +} + +# undef vasprintf +# define vasprintf local_vasprintf + +# 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 @@ -83,8 +136,8 @@ int gl_consolesafe_fprintf (FILE *restrict fp, const char *restrict format, ...) { va_list args; - char *tmpstring; va_start (args, format); + char *tmpstring; int result = vasprintf (&tmpstring, format, args); va_end (args); if (result >= 0) @@ -101,8 +154,8 @@ int gl_consolesafe_printf (const char *restrict format, ...) { va_list args; - char *tmpstring; va_start (args, format); + char *tmpstring; int result = vasprintf (&tmpstring, format, args); va_end (args); if (result >= 0) |
