1.1 --- a/src/os/windows/vm/os_windows.cpp Wed Aug 01 04:19:22 2018 -0400 1.2 +++ b/src/os/windows/vm/os_windows.cpp Thu Aug 02 03:54:51 2018 -0700 1.3 @@ -1837,6 +1837,42 @@ 1.4 st->cr(); 1.5 } 1.6 1.7 + 1.8 +int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) { 1.9 +#if _MSC_VER >= 1900 1.10 + // Starting with Visual Studio 2015, vsnprint is C99 compliant. 1.11 + int result = ::vsnprintf(buf, len, fmt, args); 1.12 + // If an encoding error occurred (result < 0) then it's not clear 1.13 + // whether the buffer is NUL terminated, so ensure it is. 1.14 + if ((result < 0) && (len > 0)) { 1.15 + buf[len - 1] = '\0'; 1.16 + } 1.17 + return result; 1.18 +#else 1.19 + // Before Visual Studio 2015, vsnprintf is not C99 compliant, so use 1.20 + // _vsnprintf, whose behavior seems to be *mostly* consistent across 1.21 + // versions. However, when len == 0, avoid _vsnprintf too, and just 1.22 + // go straight to _vscprintf. The output is going to be truncated in 1.23 + // that case, except in the unusual case of empty output. More 1.24 + // importantly, the documentation for various versions of Visual Studio 1.25 + // are inconsistent about the behavior of _vsnprintf when len == 0, 1.26 + // including it possibly being an error. 1.27 + int result = -1; 1.28 + if (len > 0) { 1.29 + result = _vsnprintf(buf, len, fmt, args); 1.30 + // If output (including NUL terminator) is truncated, the buffer 1.31 + // won't be NUL terminated. Add the trailing NUL specified by C99. 1.32 + if ((result < 0) || (result >= (int) len)) { 1.33 + buf[len - 1] = '\0'; 1.34 + } 1.35 + } 1.36 + if (result < 0) { 1.37 + result = _vscprintf(fmt, args); 1.38 + } 1.39 + return result; 1.40 +#endif // _MSC_VER dispatch 1.41 +} 1.42 + 1.43 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { 1.44 // do nothing 1.45 }