From 4dbc26af72168a2fa004d525ba865c22ae9e4b31 Mon Sep 17 00:00:00 2001 From: "Huy Q. Bui" <39697900+bqhuyy@users.noreply.github.com> Date: Sun, 8 Oct 2023 19:03:10 +0700 Subject: [PATCH] feat: support log file truncation on windows (#960) --- CMakeLists.txt | 1 + bazel/glog.bzl | 1 + src/config.h.cmake.in | 3 +++ src/logging.cc | 13 ++++++++++++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac7c1734f..67cd362c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,7 @@ check_function_exists (sigaltstack HAVE_SIGALTSTACK) check_cxx_symbol_exists (backtrace execinfo.h HAVE_EXECINFO_BACKTRACE) check_cxx_symbol_exists (backtrace_symbols execinfo.h HAVE_EXECINFO_BACKTRACE_SYMBOLS) +check_cxx_symbol_exists (_chsize_s io.h HAVE__CHSIZE_S) # NOTE gcc does not fail if you pass a non-existent -Wno-* option as an # argument. However, it will happily fail if you pass the corresponding -W* diff --git a/bazel/glog.bzl b/bazel/glog.bzl index dacd93441..71556b7cb 100644 --- a/bazel/glog.bzl +++ b/bazel/glog.bzl @@ -114,6 +114,7 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs): "-DGLOG_EXPORT=__declspec(dllexport)", "-DGLOG_NO_ABBREVIATED_SEVERITIES", "-DHAVE_SNPRINTF", + "-DHAVE__CHSIZE_S", "-I" + src_windows, ] diff --git a/src/config.h.cmake.in b/src/config.h.cmake.in index 9d6101013..462ce5d22 100644 --- a/src/config.h.cmake.in +++ b/src/config.h.cmake.in @@ -130,6 +130,9 @@ /* define if gmtime_r is available in time.h */ #cmakedefine HAVE_GMTIME_R +/* define if _chsize_s is available in io.h */ +#cmakedefine HAVE__CHSIZE_S + /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #cmakedefine LT_OBJDIR diff --git a/src/logging.cc b/src/logging.cc index 39f0c5400..719ee0ff0 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -58,6 +58,9 @@ #ifdef HAVE_SYSLOG_H # include #endif +#ifdef HAVE__CHSIZE_S +#include // for truncate log file +#endif #include #include // for errno #include @@ -2425,7 +2428,7 @@ void GetExistingTempDirectories(vector* list) { } void TruncateLogFile(const char *path, uint64 limit, uint64 keep) { -#ifdef HAVE_UNISTD_H +#if defined(HAVE_UNISTD_H) || defined(HAVE__CHSIZE_S) struct stat statbuf; const int kCopyBlockSize = 8 << 10; char copybuf[kCopyBlockSize]; @@ -2446,7 +2449,11 @@ void TruncateLogFile(const char *path, uint64 limit, uint64 keep) { // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's // rather scary. // Instead just truncate the file to something we can manage +#ifdef HAVE__CHSIZE_S + if (_chsize_s(fd, 0) != 0) { +#else if (truncate(path, 0) == -1) { +#endif PLOG(ERROR) << "Unable to truncate " << path; } else { LOG(ERROR) << "Truncated " << path << " due to EFBIG error"; @@ -2491,7 +2498,11 @@ void TruncateLogFile(const char *path, uint64 limit, uint64 keep) { // Truncate the remainder of the file. If someone else writes to the // end of the file after our last read() above, we lose their latest // data. Too bad ... +#ifdef HAVE__CHSIZE_S + if (_chsize_s(fd, write_offset) != 0) { +#else if (ftruncate(fd, write_offset) == -1) { +#endif PLOG(ERROR) << "Unable to truncate " << path; }