On Friday 21 February 2020 17:22:13 Pali Rohár wrote: > On Friday 21 February 2020 18:17:37 Liu Hao wrote: > > 在 2020/2/21 2:27, Pali Rohár 写道: > > > Hello! Based on raymod2 suggestion on IRC, I prepared full patch and > > > tested it that snprintf() and vsnprintf() works correctly. > > > > > > Patch is attached in email as jon_y on IRC suggested. I fixed directly > > > __ms_snprintf() and __ms_vsnprintf() wrappers (around msvcrt's > > > _snprintf()/_vsnprintf() calls) which are called by snprintf() and > > > vsnprintf() static functions defined in stdio.h header file. > > > > > > In patch I also removed vsnprintf == _vsnprintf and snprintf == > > > _snprintf aliases as they wrong, snprintf() is not same as msvcrt's > > > _snprintf() function, and above __ms_snprintf() or __ms_vsnprintf() > > > wrapper is needed. > > > > > > PS: Please CC me as I'm not subscribed to list. > > > > > > > Thanks. The patch looks good, except that the hunk for 'mingw-w64-tools' > > had better be moved to an individual commit. I amended it and pushed. > > Hello Liu! Thank you!
Hello! raymod2 on IRC pointed that _vscprintf() function used by above patch is not provided by original VC6 msvcrt.dll library. It was introduced in VC7 msvcr70.dll, but in may be provided in system32 msvcrt.dll. To workaround a problem when _vscprintf() is not available, I wrote a small wrapper for libmingwex which emulates _vscprintf() call via _vsnprintf() with temporary array. Patch is attached. -- Pali Rohár pali.ro...@gmail.com
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 308c1cef..353849fc 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -450,6 +450,7 @@ src_libmingwex=\ stdio/_Exit.c stdio/_findfirst64i32.c stdio/_findnext64i32.c stdio/_fstat.c \ stdio/_fstat64i32.c stdio/_ftime.c stdio/_getc_nolock.c stdio/_getwc_nolock.c stdio/_putc_nolock.c \ stdio/_putwc_nolock.c stdio/_stat.c stdio/_stat64i32.c stdio/_wfindfirst64i32.c stdio/_wfindnext64i32.c \ + stdio/_vscprintf.c \ stdio/_wstat.c stdio/_wstat64i32.c stdio/asprintf.c stdio/atoll.c stdio/fgetpos64.c \ stdio/fopen64.c stdio/fseeko32.c stdio/fseeko64.c stdio/fsetpos64.c stdio/ftello.c \ stdio/ftello64.c stdio/ftruncate64.c stdio/lltoa.c stdio/lltow.c stdio/lseek64.c \ diff --git a/mingw-w64-crt/stdio/_vscprintf.c b/mingw-w64-crt/stdio/_vscprintf.c index e69de29b..cec1841d 100644 --- a/mingw-w64-crt/stdio/_vscprintf.c +++ b/mingw-w64-crt/stdio/_vscprintf.c @@ -0,0 +1,55 @@ +#include <windows.h> +#include <msvcrt.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +static int __cdecl init_func(const char * __restrict__ format, va_list arglist); +int (__cdecl *__MINGW_IMP_SYMBOL(_vscprintf))(const char * __restrict__, va_list) = init_func; + +static int __cdecl emu_func(const char * __restrict__ format, va_list arglist) +{ + char *buffer, *new_buffer; + size_t size; + int ret; + + size = strlen(format) * 2; + buffer = malloc(size); + + if (!buffer) { + _set_errno(ENOMEM); + return -1; + } + + while ((ret = _vsnprintf(buffer, size, format, arglist)) < 0) { + size *= 2; + new_buffer = realloc(buffer, size); + if (!new_buffer) + break; + buffer = new_buffer; + } + + free(buffer); + + if (ret < 0) { + _set_errno(ENOMEM); + return -1; + } + + return ret; +} + +static int __cdecl init_func(const char * __restrict__ format, va_list arglist) +{ + HMODULE msvcrt = __mingw_get_msvcrt_handle(); + int (__cdecl *func)(const char * __restrict__, va_list) = NULL; + + if (msvcrt) + func = (void*)GetProcAddress(msvcrt, "_vscprintf"); + + if (!func) + func = emu_func; + + return (__MINGW_IMP_SYMBOL(_vscprintf) = func)(format, arglist); +}
signature.asc
Description: PGP signature
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public