diff --git a/libiberty/vprintf-support.c b/libiberty/vprintf-support.c index 5a998fbf4ae..905e86b0437 100644 --- a/libiberty/vprintf-support.c +++ b/libiberty/vprintf-support.c @@ -27,6 +27,7 @@ Floor, Boston, MA 02110-1301, USA. */ # define va_copy(d,s) __va_copy((d),(s)) #endif #include +#include #ifdef HAVE_STRING_H #include #endif @@ -37,6 +38,21 @@ extern unsigned long strtoul (); #endif #include "libiberty.h" +static inline unsigned long +do_strtoul (const char *str, char **endptr, int base) + { +#ifdef _WIN32 + /* The MSVCRT `strtoul()` function resets `errno` to zero upon success. + We must preserve it across this call. */ + int saved_errno = errno; +#endif + long value = strtoul (str, endptr, base); +#ifdef _WIN32 + errno = saved_errno; +#endif + return value; + } + int libiberty_vprintf_buffer_size (const char *format, va_list args) { @@ -65,7 +81,7 @@ libiberty_vprintf_buffer_size (const char *format, va_list args) total_width += abs (va_arg (ap, int)); } else - total_width += strtoul (p, (char **) &p, 10); + total_width += do_strtoul (p, (char **) &p, 10); if (*p == '.') { ++p; @@ -75,7 +91,7 @@ libiberty_vprintf_buffer_size (const char *format, va_list args) total_width += abs (va_arg (ap, int)); } else - total_width += strtoul (p, (char **) &p, 10); + total_width += do_strtoul (p, (char **) &p, 10); } do {