File indexing completed on 2025-07-03 08:52:58
0001
0002
0003
0004 #pragma once
0005
0006 #ifndef SPDLOG_HEADER_ONLY
0007 #include <spdlog/details/file_helper.h>
0008 #endif
0009
0010 #include <spdlog/common.h>
0011 #include <spdlog/details/os.h>
0012
0013 #include <cerrno>
0014 #include <chrono>
0015 #include <cstdio>
0016 #include <string>
0017 #include <thread>
0018 #include <tuple>
0019
0020 namespace spdlog {
0021 namespace details {
0022
0023 SPDLOG_INLINE file_helper::file_helper(const file_event_handlers &event_handlers)
0024 : event_handlers_(event_handlers) {}
0025
0026 SPDLOG_INLINE file_helper::~file_helper() { close(); }
0027
0028 SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) {
0029 close();
0030 filename_ = fname;
0031
0032 auto *mode = SPDLOG_FILENAME_T("ab");
0033 auto *trunc_mode = SPDLOG_FILENAME_T("wb");
0034
0035 if (event_handlers_.before_open) {
0036 event_handlers_.before_open(filename_);
0037 }
0038 for (int tries = 0; tries < open_tries_; ++tries) {
0039
0040 os::create_dir(os::dir_name(fname));
0041 if (truncate) {
0042
0043
0044
0045
0046 std::FILE *tmp;
0047 if (os::fopen_s(&tmp, fname, trunc_mode)) {
0048 continue;
0049 }
0050 std::fclose(tmp);
0051 }
0052 if (!os::fopen_s(&fd_, fname, mode)) {
0053 if (event_handlers_.after_open) {
0054 event_handlers_.after_open(filename_, fd_);
0055 }
0056 return;
0057 }
0058
0059 details::os::sleep_for_millis(open_interval_);
0060 }
0061
0062 throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing",
0063 errno);
0064 }
0065
0066 SPDLOG_INLINE void file_helper::reopen(bool truncate) {
0067 if (filename_.empty()) {
0068 throw_spdlog_ex("Failed re opening file - was not opened before");
0069 }
0070 this->open(filename_, truncate);
0071 }
0072
0073 SPDLOG_INLINE void file_helper::flush() {
0074 if (std::fflush(fd_) != 0) {
0075 throw_spdlog_ex("Failed flush to file " + os::filename_to_str(filename_), errno);
0076 }
0077 }
0078
0079 SPDLOG_INLINE void file_helper::sync() {
0080 if (!os::fsync(fd_)) {
0081 throw_spdlog_ex("Failed to fsync file " + os::filename_to_str(filename_), errno);
0082 }
0083 }
0084
0085 SPDLOG_INLINE void file_helper::close() {
0086 if (fd_ != nullptr) {
0087 if (event_handlers_.before_close) {
0088 event_handlers_.before_close(filename_, fd_);
0089 }
0090
0091 std::fclose(fd_);
0092 fd_ = nullptr;
0093
0094 if (event_handlers_.after_close) {
0095 event_handlers_.after_close(filename_);
0096 }
0097 }
0098 }
0099
0100 SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf) {
0101 if (fd_ == nullptr) return;
0102 size_t msg_size = buf.size();
0103 auto data = buf.data();
0104 if (std::fwrite(data, 1, msg_size, fd_) != msg_size) {
0105 throw_spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno);
0106 }
0107 }
0108
0109 SPDLOG_INLINE size_t file_helper::size() const {
0110 if (fd_ == nullptr) {
0111 throw_spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_));
0112 }
0113 return os::filesize(fd_);
0114 }
0115
0116 SPDLOG_INLINE const filename_t &file_helper::filename() const { return filename_; }
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension(
0132 const filename_t &fname) {
0133 auto ext_index = fname.rfind('.');
0134
0135
0136
0137 if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1) {
0138 return std::make_tuple(fname, filename_t());
0139 }
0140
0141
0142 auto folder_index = fname.find_last_of(details::os::folder_seps_filename);
0143 if (folder_index != filename_t::npos && folder_index >= ext_index - 1) {
0144 return std::make_tuple(fname, filename_t());
0145 }
0146
0147
0148 return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
0149 }
0150
0151 }
0152 }