aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-01-08 15:20:21 +0000
committerRon Yorston <rmy@pobox.com>2019-01-08 15:20:21 +0000
commit26a1f54837da021aeeb72680acb2feb4ea1e02da (patch)
tree831899a173b4caa86f904ede75365c772b2b8694
parenta85653040477ec4e8a722de3af5afd04ee66bd59 (diff)
downloadbusybox-w32-26a1f54837da021aeeb72680acb2feb4ea1e02da.tar.gz
busybox-w32-26a1f54837da021aeeb72680acb2feb4ea1e02da.tar.bz2
busybox-w32-26a1f54837da021aeeb72680acb2feb4ea1e02da.zip
win32: implement vsnprintf(2)
The Microsoft C runtime may include a defective version of vsnprintf. Implement a standards-compliant replacement.
-rw-r--r--include/mingw.h4
-rw-r--r--win32/winansi.c21
2 files changed, 25 insertions, 0 deletions
diff --git a/include/mingw.h b/include/mingw.h
index 2dc3ddfd7..f9c098917 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -134,6 +134,7 @@ int winansi_putchar(int c);
134int winansi_puts(const char *s); 134int winansi_puts(const char *s);
135size_t winansi_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 135size_t winansi_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
136int winansi_fputs(const char *str, FILE *stream); 136int winansi_fputs(const char *str, FILE *stream);
137int winansi_vsnprintf(char *buf, size_t size, const char *format, va_list list);
137int winansi_vfprintf(FILE *stream, const char *format, va_list list); 138int winansi_vfprintf(FILE *stream, const char *format, va_list list);
138int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2))); 139int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
139int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3))); 140int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3)));
@@ -144,6 +145,9 @@ int winansi_getc(FILE *stream);
144#define puts winansi_puts 145#define puts winansi_puts
145#define fwrite winansi_fwrite 146#define fwrite winansi_fwrite
146#define fputs winansi_fputs 147#define fputs winansi_fputs
148#if !defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO
149#define vsnprintf(buf, size, ...) winansi_vsnprintf(buf, size, __VA_ARGS__)
150#endif
147#define vfprintf(stream, ...) winansi_vfprintf(stream, __VA_ARGS__) 151#define vfprintf(stream, ...) winansi_vfprintf(stream, __VA_ARGS__)
148#define vprintf(...) winansi_vfprintf(stdout, __VA_ARGS__) 152#define vprintf(...) winansi_vfprintf(stdout, __VA_ARGS__)
149#define printf(...) winansi_printf(__VA_ARGS__) 153#define printf(...) winansi_printf(__VA_ARGS__)
diff --git a/win32/winansi.c b/win32/winansi.c
index 167b4b0b1..9e7d10a56 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -552,6 +552,27 @@ int winansi_fputs(const char *str, FILE *stream)
552 return ansi_emulate(str, stream) == EOF ? EOF : 0; 552 return ansi_emulate(str, stream) == EOF ? EOF : 0;
553} 553}
554 554
555#if !defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO
556/*
557 * Prior to Windows 10 vsnprintf was incompatible with the C99 standard.
558 * Implement a replacement using _vsnprintf.
559 */
560int winansi_vsnprintf(char *buf, size_t size, const char *format, va_list list)
561{
562 size_t len;
563 va_list list2;
564
565 va_copy(list2, list);
566 len = _vsnprintf(NULL, 0, format, list2);
567 if (len < 0)
568 return -1;
569
570 _vsnprintf(buf, size, format, list);
571 buf[size-1] = '\0';
572 return len;
573}
574#endif
575
555int winansi_vfprintf(FILE *stream, const char *format, va_list list) 576int winansi_vfprintf(FILE *stream, const char *format, va_list list)
556{ 577{
557 int len, rv; 578 int len, rv;