fix: 修复MaaCore asst.log文件句柄泄露 (#12639)

* fix: 尝试修复日志文件句柄泄露

* fix: platform

* fix: platform

* fix: platform

* fix: platform

* fix: cr-lf

* chore: useless
This commit is contained in:
status102
2025-05-11 19:34:01 +08:00
committed by GitHub
parent 894d540649
commit baff16c024

View File

@@ -1,5 +1,9 @@
#pragma once
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
#include <filesystem>
#include <fstream>
#include <functional>
@@ -572,12 +576,7 @@ public:
{
if (c != traits_type::eof()) {
ch = static_cast<char>(c);
if (ch == '\n') {
count += NewLineSize;
}
else {
count++;
}
count++;
if (dest) {
dest->sputc(ch);
}
@@ -604,11 +603,6 @@ public:
}
private:
#if defined(_WIN32) || defined(_WIN64)
const static std::size_t NewLineSize = 2; // \r\n;
#else
const static std::size_t NewLineSize = 1; // \n;
#endif
char ch = 0;
std::filebuf* dest;
std::streamsize count = 0;
@@ -784,8 +778,43 @@ private:
void LoadFileStream()
{
m_ofs = std::ofstream(m_log_path, std::ios::out | std::ios::app);
m_file_size = std::filesystem::file_size(m_log_path);
#ifdef _WIN32
FILE* fp = nullptr;
int file_handle = -1;
int oflag = _O_WRONLY | _O_APPEND | _O_CREAT | _O_BINARY | _O_NOINHERIT; // 写入、追加、创建、二进制、不可继承
int shflag = _SH_DENYWR; // 允许其他进程读取但不能写入
int pmode = _S_IREAD | _S_IWRITE; // 读写权限
// 打开文件
if (_sopen_s(&file_handle, utils::path_to_utf8_string(m_log_path).c_str(), oflag, shflag, pmode) == 0) {
// 文件打开成功转换为FILE*指针
fp = _fdopen(file_handle, "a"); // 使用追加模式
if (!fp) {
// 如果转换失败,关闭文件句柄
_close(file_handle);
}
}
if (!fp) {
// 打开失败时回退到原始方法
m_ofs = std::ofstream(m_log_path, std::ios::out | std::ios::ate);
}
else {
// 使用文件指针创建新的std::ofstream
// 注意传递文件指针的所有权给ofstream
m_ofs = std::ofstream(fp);
// 如果需要,这里还可以添加一个安全检查
if (!m_ofs) {
fclose(fp);
m_ofs = std::ofstream(m_log_path, std::ios::out | std::ios::ate);
}
}
#else
m_ofs = std::ofstream(m_log_path, std::ios::out | std::ios::ate);
#endif
// 获取文件大小并设置缓冲区
m_file_size = std::filesystem::exists(m_log_path) ? std::filesystem::file_size(m_log_path) : 0;
m_buff = LogStreambuf(m_ofs.rdbuf());
m_of.rdbuf(&m_buff);
}