1492 // chop off newline character |
1492 // chop off newline character |
1493 char* nl = strchr(buf, '\n'); |
1493 char* nl = strchr(buf, '\n'); |
1494 if (nl != NULL) *nl = '\0'; |
1494 if (nl != NULL) *nl = '\0'; |
1495 } |
1495 } |
1496 |
1496 |
1497 int os::log_vsnprintf(char* buf, size_t len, const char* fmt, va_list args) { |
1497 int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) { |
1498 int ret = vsnprintf(buf, len, fmt, args); |
1498 #if _MSC_VER >= 1900 |
1499 // Get the correct buffer size if buf is too small |
1499 // Starting with Visual Studio 2015, vsnprint is C99 compliant. |
1500 if (ret < 0) { |
1500 int result = ::vsnprintf(buf, len, fmt, args); |
1501 return _vscprintf(fmt, args); |
1501 // If an encoding error occurred (result < 0) then it's not clear |
1502 } |
1502 // whether the buffer is NUL terminated, so ensure it is. |
1503 return ret; |
1503 if ((result < 0) && (len > 0)) { |
|
1504 buf[len - 1] = '\0'; |
|
1505 } |
|
1506 return result; |
|
1507 #else |
|
1508 // Before Visual Studio 2015, vsnprintf is not C99 compliant, so use |
|
1509 // _vsnprintf, whose behavior seems to be *mostly* consistent across |
|
1510 // versions. However, when len == 0, avoid _vsnprintf too, and just |
|
1511 // go straight to _vscprintf. The output is going to be truncated in |
|
1512 // that case, except in the unusual case of empty output. More |
|
1513 // importantly, the documentation for various versions of Visual Studio |
|
1514 // are inconsistent about the behavior of _vsnprintf when len == 0, |
|
1515 // including it possibly being an error. |
|
1516 int result = -1; |
|
1517 if (len > 0) { |
|
1518 result = _vsnprintf(buf, len, fmt, args); |
|
1519 // If output (including NUL terminator) is truncated, the buffer |
|
1520 // won't be NUL terminated. Add the trailing NUL specified by C99. |
|
1521 if ((result < 0) || (result >= len)) { |
|
1522 buf[len - 1] = '\0'; |
|
1523 } |
|
1524 } |
|
1525 if (result < 0) { |
|
1526 result = _vscprintf(fmt, args); |
|
1527 } |
|
1528 return result; |
|
1529 #endif // _MSC_VER dispatch |
1504 } |
1530 } |
1505 |
1531 |
1506 static inline time_t get_mtime(const char* filename) { |
1532 static inline time_t get_mtime(const char* filename) { |
1507 struct stat st; |
1533 struct stat st; |
1508 int ret = os::stat(filename, &st); |
1534 int ret = os::stat(filename, &st); |